21👍
Overriding the create()
method of the serializer as
class ArticleSerializer(serializers.ModelSerializer):
tags = serializers.CharField()
class Meta:
model = Article
fields = '__all__'
def create(self, validated_data):
tag = validated_data.pop('tags')
tag_instance, created = Tag.objects.get_or_create(name=tag)
article_instance = Article.objects.create(**validated_data, tags=tag_instance)
return article_instance
2👍
Okay, thanks to @JPG for their help. This is what I’ve ended up with. It allows users to add space delimited tags into a CharField
on the /api/blog/article
endpoint. When a POST request is performed, the tags are split on spaces, get_or_create()
d (for this to work I needed to make Tag.name
the primary key), and then added to the Article
with article.tags.set(tag_list)
. As @JPG and @Martins suggested, a ManyToManyField()
was the best way to do this.
Here is my full code:
serializers.py:
class ArticleSerializer(serializers.ModelSerializer):
class TagsField(serializers.CharField):
def to_representation(self, tags):
tags = tags.all()
return "".join([(tag.name + " ") for tag in tags]).rstrip(' ')
tags = TagsField()
class Meta:
model = Article
fields = '__all__'
def create(self, validated_data):
tags = validated_data.pop('tags') # Removes the 'tags' entry
tag_list = []
for tag in tags.split(' '):
tag_instance, created = Tag.objects.get_or_create(name=tag)
tag_list += [tag_instance]
article = Article.objects.create(**validated_data)
print(tag_list)
article.tags.set(tag_list)
article.save()
return article
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = '__all__'
Note that I had to create a custom TagField()
and override to_representation()
. This is because if I used a regular serializer.CharField()
tags were displayed as: “Blog.tag.None” instead of the tag values, like this:
models.py:
class Tag(models.Model):
name = models.CharField(max_length=32, primary_key=True)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
class Article(models.Model):
title = models.CharField(max_length=256)
author = models.ForeignKey(User, on_delete=models.CASCADE)
content = models.TextField()
date = models.DateTimeField(auto_now_add=True)
tags = models.ManyToManyField(Tag)
def __str__(self):
return self.title
class Meta:
ordering = ('date', 'id')
- Image Conversion – Cannot write mode RGBA as JPEG
- Serialize multiple models and send all in one json response django rest framework
- Creating an entire web application using django admin
- Assign Value of Named URL to a Variable in Django Templates