Django rest framework- writable(create,update)double nested serializer

问题描述 投票:3回答:1

我正在尝试使用DJANGO REST FRAMEWORK创建嵌套的序列化器。

但是我不知道如何在serializer.py中使用create update方法。我已经创建了模型和一些可运行的序列化程序。

models.py

class JournalEntry(models.Model):
    CHOICES = (
        ('SALES', 'Sales'),
        ('PURCHASE', 'Purchase'),
        ('DEBITNOTE', 'DebitNote'),
        ('CREDITNOTE', 'CreditNote'),
        ('COSTOMER_RECIEPT', 'CustomerReceipt'),
        ('SUPPLIER_PAYMENT', 'SupplierPayment'),
        ('EXPENSE', 'Expense'),
        ('JOURNAL', 'Journal'),
    )

    date = models.DateField()
    transaction_type = models.CharField(max_length=15, choices=CHOICES, default='SALES',null=True, blank=True)
    description = models.CharField(max_length=15,null=True, blank=True)

    @property
    def child(self):
        return self.journalitem_set.all()

class JournalItem(models.Model):
    journal_entry = models.ForeignKey('core.JournalEntry', on_delete=models.CASCADE)
    account = models.CharField(max_length=15, choices=CHOICES, default='SALES',null=True, blank=True)
    partner = models.ForeignKey(Customer, on_delete=models.CASCADE, null=True, blank=True)
    debit_amount = models.DecimalField(max_digits=15,decimal_places=2,null=True, blank=True)
    credit_amount = models.DecimalField(max_digits=15,decimal_places=2,null=True, blank=True)


class CustomerReceipt(models.Model):
    reciept_no = models.IntegerField()
    journal_entry = models.ForeignKey(JournalEntry, on_delete=models.CASCADE, null=True, blank=True)

serializer.py,一些必需的序列化程序已经完成。

class JournalItemSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(required=False)
    class Meta:
        model = JournalItem
        fields = [
        'id','journal_entry',
        'account','partner',
        'debit_amount','credit_amount'
        ]
        read_only_fields = ('journal_entry',)

class JournalEntrySerializer(serializers.ModelSerializer):
    child = JournalItemSerializer(many=True)

    class Meta:
        model = JournalEntry
        fields = ('id','date','transaction_type','description','child')

    def create(self, validated_data):
        albums_data = validated_data.pop('child')
        musician = JournalEntry.objects.create(**validated_data)
        for album_data in albums_data:
            JournalItem.objects.create(journal_entry=musician, **album_data)
        return musician

    def update(self, instance, validated_data):
        child = validated_data.pop('child')
        # albums = (instance.child).all()
        # albums = list(albums)
        instance.date = validated_data.get('date', instance.date)
        instance.transaction_type = validated_data.get('transaction_type', instance.transaction_type)
        instance.description = validated_data.get('description', instance.description)

        instance.save()
        keep_choices = []
        for choice in child:
            if "id" in choice.keys():
                if JournalItem.objects.filter(id=choice["id"]).exists():
                    c = JournalItem.objects.get(id=choice["id"])
                    c.account = choice.get('account', c.account)
                    c.partner = choice.get('partner', c.partner)
                    c.debit_amount = choice.get('debit_amount', c.debit_amount)
                    c.credit_amount = choice.get('credit_amount', c.credit_amount)
                    c.save()
                    keep_choices.append(c.id)
                else:
                    continue
            else:
                c = JournalItem.objects.create(**choice, journal_entry=instance)
                keep_choices.append(c.id)
        for choice in instance.child:
            if choice.id not in keep_choices:
                choice.delete()

        return instance

我需要在CustomerReceiptSerializer中添加createupdate方法。我需要在corersponding api上执行所有操作(DELETE,PUT,PATCH $ POST)。


class CustomerReceiptSerializer(serializers.ModelSerializer):
    journal_entry = JournalEntrySerializer()
    class Meta:
        model = CustomerReceipt
        # fields = ('reciept_no', 'journal_entry')
        fields = "__all__"
    def create:
         ......
    def update:
         ......

class CustomerReceiptViewSet(viewsets.ModelViewSet):
    serializer_class = serializers.CustomerReceiptSerializer
    queryset = models.CustomerReceipt.objects.all()

输出类似,

{
    "id": 1,
    "journal_entry": {
        "id": 1,
        "date": "2019-05-09",
        "transaction_type": "SALES",
        "description": "description",
        "child": [
            {
                "id": 1,
                "journal_entry": 1,
                "account": "Sales",
                "partner": null,
                "debit_amount": "400.00",
                "credit_amount": "400.00"
            },
           {
                "id": 1,
                "journal_entry": 1,
                "account": "Purchase",
                "partner": null,
                "debit_amount": "800.00",
                "credit_amount": "400.00"
            }
        ]
    },
    "reciept_no": 1
}

json data for post into api is like,

{
    "reciept_no": 1
    "journal_entry": {
        "date": "2019-05-09",
        "transaction_type": "SALES",
        "description": "description",
        "child": [
            {
                "account": "Sales",
                "partner": null,
                "debit_amount": "400.00",
                "credit_amount": "400.00"
            },
           {
                "account": "Purchase",
                "partner": null,
                "debit_amount": "800.00",
                "credit_amount": "400.00"
            }
        ]
    }
}
iam using ,
Django - 2.1.3,
djangorestframework - 3.9.0 




python django django-models django-rest-framework serializer
1个回答
0
投票

在JournalEntrySerializer中,与CustomerReceipt模型创建关系。

child = JournalItemSerializer(many=True)
costumer = CustomerReceipt()

注意:CustomerReceipt()也可能会收到很多= True。

然后,在JournalEntrySerializer的create()和update()中,您可以记录CustomerReceipt。

This reference can help

© www.soinside.com 2019 - 2024. All rights reserved.