Since there are a few questions about m2m and DRF I'll try narrow down what specifically I'm interested in. Let's call the two models 'article' and 'publication'. Assume that:
The 'publication' object already exists.
The 'article' object may or may not exist. specifically:
a) If a previous publication contained the article, then it will already be there.
b) If not, then the article will need to be created.
I want to send a post http request with the article data in the body and the publication id available from the url which will:
a) if the article already exists, link it to the publication
b) if the article does not exist, create it, and then link it to the publication
Going for the 'default' strategy below did not work out. I can think of two ways to approach this problem:
Overriding the create method on the article serializer. However I'm scepticle of doing that since this seems like a problem that should be common and have a non-custom solution.
- Creating an endpoint to directly work with the 'through' model. I could then split up the process into two steps (and 2 requests) where I first get_or_create the article, and then post to the through model endpoint to create the link.
Are there any other approaches or built-in DRF solutions to this problem?
Here's where I'm at currently:
models.py
class Publication(models.Model):
name = models.CharField(max_length=255, unique=True)
collection = models.CharField(max_length=255)
class Article(models.Model):
major = models.IntegerField()
minor = models.IntegerField()
publication = models.ManyToManyField(Publication)
class Meta:
constraints = [models.UniqueConstraint(fields=['major', 'minor'], name='unique_article')]
views.py
class ArticleViewSet(viewsets.ModelViewSet):
serializer_class = ArticleSerializer
queryset = Article.objects.all()
serializers.py
class ArticleSerializer(serializers.ModelSerializer):
publication = serializers.SlugRelatedField(slug_field='name', queryset=Publication.objects.all()), many=True)
class Meta:
model = Article
fields = '__all__'
When posting to this endpoint I'll get a 'duplicate entry' integrity error if the article does already exist, instead of the article then just being linked.