I'm trying to use the Django Rest Framework serializers to make API's for my front-end to create / update and delete articles in a store. These articles can have multiple prices (depending on time). So there is a one-to-many relation from article (one) to price (many). I have defined this in models.py:
class Article(models.Model):
article_id = models.AutoField(primary_key=True, verbose_name="Article ID")
article_name = models.CharField(max_length=250, verbose_name="Name")
article_order = models.IntegerField(verbose_name="Order")
class Price(models.Model):
price_id = models.AutoField(primary_key=True, verbose_name="Price ID")
article_id = models.ForeignKey(Article, on_delete=models.CASCADE, verbose_name="Article ID", related_name="Prices")
price_price = models.DecimalField(max_digits=6, decimal_places=2, verbose_name="Price")
My serializers.py file looks like this:
from rest_framework import serializers
from .models import *
class PriceSerializer(serializers.ModelSerializer):
class Meta:
model = Price
fields = ('price_price',)
class ArticleSerializer(serializers.ModelSerializer):
Prices = PriceSerializer(many=True)
def create(self, validated_data):
prices_data = validated_data.pop('Prices')
article = Article.objects.create(**validated_data)
for price_data in prices_data:
Price.objects.create(article_id=article, **price_data)
return article
def update(self, instance, validated_data):
prices_data = validated_data.pop('Prices')
Article.objects.filter(article_id=instance.article_id).update(**validated_data)
for price_data in prices_data:
Price.objects.get_or_create(article_id=instance, **price_data)
return instance
class Meta:
model = Article
fields = '__all__'
This works perfectly and I can create a new article-price measurement with this data: (article_order will be used later for ordering the list)
{"Prices":[{"price_price":"1"}],"article_name":"Article A","article_order":"1"}
Until this point, everything is working as expected. But when I try to update the prices, the Price.objects.get_or_create() statement does not recognize existing prices. For example: when the first price is €10, then €20 and then again €10, the last price will not be inserted because the get_or_create statement does not recognize this as a new instance of the price model. That probably makes sense, because the PriceSerializer does not serialize the price_id. But when I change the serializer to:
class PriceSerializer(serializers.ModelSerializer):
class Meta:
model = Price
fields = '__all__
, I can no longer create instances because the ArticleSerializer is requiring an article_id for the Price instance (but that doesn't exist yet).
Does anyone have an idea how to solve this problem? The DRF documentation only includes the create statement for this type of nested serializer.
https://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers