3

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 




1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.