【问题标题】:Nested serializer does not serialize the second serializer嵌套序列化器不序列化第二个序列化器
【发布时间】:2017-01-26 08:30:50
【问题描述】:

我想使用嵌套序列化程序。我已关注文档http://www.django-rest-framework.org/api-guide/relations/

我正在使用 Django REST 3.5.3 和 Django 1.9.12。

这是我的modelsserializers

models

class Budget(AbstractModelController):
    CANCELED = -1
    CREATED = 0
    QUOTATION = 1
    INVOICED = 2
    PART_PAID = 3
    COMPLETED = 4

    STATUS_CHOICES = (
        (CANCELED, _("Canceled")),
        (CREATED, _("Created")),
        (QUOTATION, _("Quotation")),
        (INVOICED, _("Invoiced")),
        (PART_PAID, _("Part Paid")),
        (COMPLETED, _("Completed"))
    )

    project = models.ForeignKey(Project, related_name="budgets", verbose_name=_("Project"))
    status = models.IntegerField(choices=STATUS_CHOICES, default=CREATED, verbose_name=_("Status"))
    name = models.CharField(max_length=200, verbose_name=_("Name"))
    value = models.DecimalField(max_digits=10, decimal_places=2, verbose_name=_("Value"))
    start_date = models.DateTimeField(verbose_name=_("Start date"))
    end_date = models.DateTimeField(verbose_name=_("End date"))

    class Meta:
        ordering = ("-id", )

    def __str__(self):
        return "{}: {}".format(self.project.name, self.name)

    def get_absolute_url(self):
        return reverse_lazy("budget:detail", kwargs={"pk": self.id})

class Payment(AbstractModelController):

    class PaymentState(DjangoChoices):
        Paid = ChoiceItem("P")
        Unpaid = ChoiceItem("U")

    budget = models.ForeignKey(Budget, null=True, blank=True)
    description = models.CharField(max_length=255)
    ratio = models.SmallIntegerField(validators=[validate_boundary], verbose_name="Ratio(%)")
    state = models.CharField(max_length=1, choices=PaymentState.choices, validators=[PaymentState.validator])

serializers:

class BudgetSerializer(serializers.ModelSerializer):
    project = ProjectSerializer()
    payments = PaymentSerializer(many=True, read_only=True)

    class Meta:
        model = Budget
        exclude = EXCLUDE_MODEL_CONTROLLER_FIELDS


class PaymentSerializer(ModelControllerSerializerMixin):
    class Meta:
        model = Payment
        fields = [
            "budget",
            "description",
            "ratio",
            "state",
        ]

payment 表中。有多条记录,参考budget_id=1

    {
        "budget": 1,
        "description": "First round",
        "ratio": 30,
        "state": "P"
    },
    {
        "budget": 1,
        "description": "Second round",
        "ratio": 30,
        "state": "U"
    },
    {
        "budget": 1,
        "description": "Final round",
        "ratio": 40,
        "state": "U"
    },
    {
        "budget": 1,
        "description": "Final round",
        "ratio": 40,
        "state": "U"
    }

这是budget serializer 输出。它不包含嵌套的序列化数据

{
        "id": 1,
        "project": {
            "id": 1,
            "company": {
                "id": 1,
                "name": "Sarit Enterprise",
                "phone_number": "0841021711",
                "email": "cs.sarit@gmail.com",
                "address": "bkk@bkk",
                "tax_id": "67890",
                "organization": 1
            },
            "name": "Project"
        },
        "status": 0,
        "name": "Budget",
        "value": 0.0,
        "start_date": "2016-05-17T17:00:00Z",
        "end_date": "2016-06-29T17:00:00Z"
    }

我是否错过了一些要点?

【问题讨论】:

    标签: python django serialization django-rest-framework


    【解决方案1】:

    如果你查看Reverse Relations的文档:

    请注意,ModelSerializerHyperlinkedModelSerializer 类不会自动包含反向关系。要包含反向关系,您必须将其显式添加到字段列表中。

    您通常需要确保已在关系上设置了适当的 related_name 参数,您可以将其用作字段名称。

    如果您没有为反向关系设置related name,则需要在字段参数中使用自动生成的相关名称。

    考虑到第二点,您需要在付款模型的预算字段中添加related_name

    budget = models.ForeignKey(Budget, null=True, blank=True, related_name='payments')
    

    【讨论】:

    • 非常感谢。 Reverse Relation 对我来说是一个新知识。
    【解决方案2】:

    我错过了related_name

    class Payment(AbstractModelController):
    
        class PaymentState(DjangoChoices):
            Paid = ChoiceItem("P")
            Unpaid = ChoiceItem("U")
    
        budget = models.ForeignKey(Budget, related_name='payments', null=True, blank=True)
        description = models.CharField(max_length=255)
        ratio = models.SmallIntegerField(validators=[validate_boundary], verbose_name="Ratio(%)")
        state = models.CharField(max_length=1, choices=PaymentState.choices, validators=[PaymentState.validator])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-28
      • 2021-07-24
      • 2017-07-12
      • 2018-07-05
      • 2020-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多