简体   繁体   中英

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

I am trying to create a nested serializer using DJANGO REST FRAMEWORK.

But I don't know how to use create update methods in serializer.py. I already have created models and some working serializers.

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, some required serializers are already did.

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

i need to add create and update method in CustomerReceiptSerializer .i need to work all operation(DELETE,PUT,PATCH $ POST) on the corersponding api.


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()

the output like,

{
    "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 




Within the JournalEntrySerializer, create a relationship with the CustomerReceipt model.

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

Note: CustomerReceipt() may also receive many=True.

Then, in create() and update() of JournalEntrySerializer, you can record CustomerReceipt.

This reference can help

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM