Django Restful:嵌套的Serializers

时间:2017-02-22 16:50:08

标签: django serialization nested django-rest-framework

我正在添加一个'测试'字段到我的样本'模型,其中'测试'将是一个' TestRequest'对象。目前,我收到此错误:

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'.

'测试'不是我模特的一个领域。我只是想将它添加到序列化数据中。目前,我可以使用嵌套的序列化器来为“klass”工作。但那是因为它在模型中定义了。

型号:

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)

我宁愿不必将字段添加到模型中。 A'样本'可以有很多' TestRequest,但是有一个' TestRequest'只能有一个' Sample'。

如何让我的序列化程序添加'测试'模型中没有的字段?

1 个答案:

答案 0 :(得分:0)

SampleSerializer中。您指定的“tests”不在您模型的Sample课程中......

使用嵌套的SerializerMethodField,如下所示....

tests = serializers.SerializerMethodField()

def get_tests(self, obj):

    var=TestRequestSerializer(obj.id)
     return var.data