2016-11-18 1 views
0

У меня есть следующие модели:Выполнение функции в качестве источника в Serializer Джанго

class A(Model): 
    pass 

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

А теперь я хочу, чтобы сериализовать Объект, в котором я хочу, чтобы иметь первый объект б. Я использовал этот код:

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. Has это поведение в последнее время изменилось?
  2. Как я могу взять первый объект b внутри сериализации?

ответ

1

спецификации вокруг source не изменилось, как вы можете прочитать в doc:

source : The name of the attribute that will be used to populate the field. May be a method that only takes a self argument, such as URLField(source='get_absolute_url') , or may use dotted notation to traverse attributes, such as EmailField(source='user.email') .

Таким образом, вы должны пройти атр или метод имя класса, который экземпляр является сериализации, в вашем случае A или attr или метод для перемещения атрибутов (с точечной нотацией), но всегда начиная с attr/метода класса A.

Таким образом, вы можете решить вашу проблему так:

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__ 
+1

Это работает как шарм, спасибо! :-D – physicalattraction

Смежные вопросы