在Django的Serializer

时间:2016-11-18 16:45:27

标签: django python-3.x serialization

我有以下型号:

class A(Model):
    pass

class B(Model):
    a = ForeignKey(A, related_name = 'b')
    b_field = CharField(max_length=64)

我现在想序列化一个A对象,我希望在其中拥有第一个b对象。我曾经有过这段代码:

class BSerializer(ModelSerializer):

    class Meta:
        model = B
        fields = '__all__'

class ASerializer(ModelSerializer):
    b = BSerializer(source='b.first')

    class Meta:
        model = A
        fields = '__all__'

这曾经有用,但现在我的单元测试失败了:

AttributeError: Got AttributeError when attempting to get a value for field `b_field` on serializer `BSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `method` instance.
Original exception text was: 'function' object has no attribute 'b_field'.

显然,b.first是一个函数,而且确实没有这样的属性。我希望源字段执行该功能。我尝试了以下一行:

    b = BSerializer(source='b.first')

但是这给出了以下错误:

AttributeError: Got AttributeError when attempting to get a value for field `b` on serializer `ASerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `A` instance.
Original exception text was: 'RelatedManager' object has no attribute 'first()'.
  1. 最近是否已更改此行为?
  2. 如何将a中的第一个b对象带入序列化?

1 个答案:

答案 0 :(得分:1)

source周围的规格没有改变,您可以在doc阅读:

  

source:将用于填充字段的属性的名称。可能是仅采用自我参数的方法,例如URLField(source='get_absolute_url'),或者可以使用虚线表示法来遍历属性,例如EmailField(source='user.email')

因此,您应该传递一个attr或方法名称正在序列化的实例,在您的情况下A,或attr或方法来遍历属性(使用点表示法)但始终从A类的attr /方法开始。

所以,你可以这样解决问题:

class A(Model):
    def first_b(self):
        return self.b.first()


class ASerializer(ModelSerializer):
    b = BSerializer(source='first_b')

    class Meta:
        model = A
        fields = '__all__