串行器丢弃相关的字段数据(嵌套序列化器和fk相关字段的相同字段)

时间:2017-06-13 04:54:39

标签: python django django-rest-framework

我的序列化器神秘地放弃了一些相关领域而不是其他领域。我试图找到有关验证方法顺序的文档,但在DRF的网站上找不到任何内容。然后我向一堆方法添加了一些print语句,以查看值被删除的位置:

  • 字段值出现在请求
  • 的视图中
  • 字段值显示在validate_empty_values调用
  • 没有为相关字段调用validate_<field_name>方法,但我怀疑这些方法不会被调用相关字段
  • 验证方法中不存在字段值

这很奇怪,其他相关字段的定义方式完全相同,并且正在按预期工作。

class ExampleSerializer(ModelSerializer):
    account = AccountSerializer(read_only=True)
    address = AddressSerializer()
    marketplace = MarketplaceSerializer(read_only=True)
    product = ProductSerializer(read_only=True)
    ...

    class Meta:
        model = ExampleOrder
        fields = (
            'id',
            'marketplace', 
            'account',
            'product',
            'address',
            ....
        )


    def validate_empty_values(self, data):
        print('validating empty: ', data)  # value present at this stage
        filtered = {}
        for key, value in data.items():
            if not key:
                continue
            if value == "" or value == "null":
                value = None
            filtered[key] = value
        print('filtered: ', filtered)  # values are present here after filtering empty keys
        return super(PurchaseOrderSerializer, self).validate_empty_values(filtered)

    def validate(self, attrs):
        print('validate all: ', attrs)  # values are not present here
        ...

    def validate_<fieldname>(self, value):
        print('related field: ', value)  # doesnt get called but I suspect related fields do not call this on validate field
        ...

    def update(self, instance, validated_data):
        print('updating: ', validated_data)  # doesn't reach this method
        ...

在上面的示例中,如果序列化程序为read_only,则只有市场和地址序列化其值或获取相应的模型。我上面声明的所有其他相关字段由于某种原因被过滤掉,数据永远不会进入验证方法,并且因为这些字段是必需的,所以会引发验证错误。相关的序列化器以标准方式定义,不会覆盖任何内容:

class AddressSerializer(ModelSerializer):

    class Meta:
        model = Address
        fields = (
            'id',
            'address_line1',
            'address_line2',
            'city',
            'state',
            'zipcode',
        )

以下是使用attrs方法的validate示例:

OrderedDict([
    ... 
    ('address', OrderedDict([
        ('address_line1', '123 STREET LN'), 
        ('address_line2', ''), 
        ('city', 'SPRINGFIELD'), 
        ('state', 'MA'), 
        ('zipcode', '12345-2926')
    ])), 
    ('user', <User: me>), 
    ('marketplace', <MarketplaceAccount: Marketplace1:ABCDEFGH123>),
    ...
])

正如您所看到的那样,地址已被序列化并且市场对象已被提取,因此问题似乎不是read_only。最新DRF的验证顺序是什么?如何让其他read_only字段返回其各自的模型,如市场字段?任何方向都会受到赞赏。

EDIT1: 型号:

class ExampleOrder(models.Model):
    ...
    marketplace = models.ForeignKey('accounts.MarketplaceAccount', null=True, blank=True)
    user = models.ForeignKey(User, related_name='orders')
    product = models.ForeignKey('products.Product',
                                         related_name='orders',
                                         null=True,
                                         blank=True,
                                         on_delete=models.SET_NULL)
    address = models.ForeignKey('accounts.Address',
                                         related_name='orders',
                                         on_delete=models.CASCADE,
                                         null=True,
                                         blank=True)
    account = models.ForeignKey('accounts.Account',
                                       related_name='orders',
                                       null=True,
                                       blank=True,
                                       on_delete=models.SET_NULL)
    ...

    class Meta:
        unique_together = (('user', 'order_id', 'marketplace'),)

EDIT1:

经过深入挖掘后,我发现了这些帖子:

似乎单独的视图,视图集中的单独序列化程序或同一序列化程序中用于处理读/写的单独字段是方法,但这些帖子是DRF 3.0之前我认为并且我不确定这仍然是推荐的方式。另外,我心中最大的问题是:

为什么市场对象被正确序列化但其他对象不是?我认为无论是全部还是全部都不会以这种方式处理。

0 个答案:

没有答案