2017-02-22 11 views
0

Я добавляю поле «тесты» к моей модели «Образец», где «тесты» будут списком объектов «TestRequest». В настоящее время я получаю эту ошибку:Django Restful: Вложенные сериализаторы

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

«тесты» не являются полем на моей модели. Я просто пытаюсь добавить его к сериализованным данным. В настоящее время я могу заставить вложенный сериализатор работать для «класс», но это потому, что он определен в модели.

Модели:

class Sample(models.Model): 
    name = models.CharField(max_length=50, null=False, blank=False) 
    comments = models.TextField(null=True, blank=True) 
    klass = models.ForeignKey('samples.Batch', null=True, blank=True, 
     related_name='samples', verbose_name='Batch') 
    product = models.ForeignKey('customers.Product', blank=False) 

    NOTRECEIVED = 'nr' 
    RECEIVED = 'rc' 
    DISCARDED = 'dc' 
    DEPLETED = 'dp' 

    SAMPLE_STATUS = (
     (NOTRECEIVED, 'not received'), 
     (RECEIVED, 'received'), 
     (DISCARDED, 'discarded'), 
     (DEPLETED, 'depleted'), 
    ) 

    status = models.CharField(
     max_length=2, choices=SAMPLE_STATUS, default=NOTRECEIVED) 
    is_recycling = models.BooleanField(default=False) 
    is_submitted = models.BooleanField(default=False) 

    received_date = models.DateTimeField(
     _('date received'), null=True, blank=True) 


class TestRequest(models.Model): 
     client = models.ForeignKey('customers.Client') 
     company = models.ForeignKey('customers.Company') 
     sample = models.ForeignKey('samples.Sample') 
     procedure_version = models.ForeignKey('registery.ProcedureVersion') 
     replicates = models.PositiveIntegerField(editable=True, null=True, blank=True) 
     created_date = models.DateTimeField('Date created', auto_now_add=True) 
     last_updated = models.DateTimeField(auto_now=True) 
     comments = models.TextField('Comments', blank=True) 

сериализаторы:

class TestSerializer(serializers.ModelSerializer): 
    href = serializers.HyperlinkedIdentityField(lookup_field='pk', lookup_url_kwarg='pk', read_only=True, view_name='samples_api:test-detail') 

    class Meta: 
     model = TestRequest 
     fields = ('id', 'href',) 

class SampleBatchSerializer(serializers.ModelSerializer): 
    href = serializers.HyperlinkedIdentityField(
     lookup_field='pk', lookup_url_kwarg='batch_pk', read_only=True, view_name='samples_api:batch-detail') 

    class Meta: 
     model = Batch 
     fields = ('id', 'href',) 

class SampleSerializer(serializers.ModelSerializer): 
    tests = TestSerializer(many=True) 
    klass = SampleBatchSerializer(many=False) 

    class Meta: 
     model = Sample 
     # list_serializer_class = FilteredListSerializer 
     fields = ('id', 'name', 'tests', 'klass',) 

    def create(self, validated_data): 
     ... 

    def update(self, instance, validated_data): 
     ... 

Viewsets:

class TestRequestViewSet(viewsets.ModelViewSet): 
    """ 
    Viewset for the TestRequest model 
    """ 
    serializer_class = TestRequestSerializer 

    def get_queryset(self): 
     client = get_object_or_404(Client, user=self.request.user) 
     return TestRequest.objects.filter(company=client.company) 

    def perform_create(self, serializer): 
     # Override default creatation to provide request based information. 
     client = get_object_or_404(Client, user=self.request.user) 
     company = client.company 
     serializer.save(client=client, company=company) 

class SampleViewSet(viewsets.ModelViewSet): 
    """ 
    Viewset for the Sample model 
    """ 
    serializer_class = SampleSerializer 

    def get_queryset(self): 
     client = get_object_or_404(Client, user=self.request.user) 
     return Sample.objects.filter(klass__company=client.company) 

Я предпочел бы не добавлять поля к модели. «Образец» может иметь много «TestRequest», но «TestRequest» может иметь только один «образец».

Как получить мой сериализатор, чтобы добавить поле «тесты», которое отсутствует в модели?

ответ

0

в вашем SampleSerializer. Вы указали «tests», который не находится в вашем Sample класса в модели ...

Используйте вложенную SerializerMethodField, как показано ниже ....

tests = serializers.SerializerMethodField() 

def get_tests(self, obj): 

    var=TestRequestSerializer(obj.id) 
    return var.data 
Смежные вопросы