Django rest framework - Create or update values fr

2019-07-18 10:16发布

问题:

I am very much new to Django and Django Rest Framework. I have an API whose json format is as below (Simplified version for sake of simplicity)

{
    "title" : "Lorem ipsum is a dummy title",
    "content" : "Lorem ipsum is a demo content"
    "tags" : ["Movies", "Food"]
}

Here is how my model looks like:

class Tag(models.Model):

    class Meta:
         verbose_name_plural = "Tags"

    name = models.CharField(max_length=200)

    def __str__(self):
        return self.name

class Post(models.Model):

    class Meta:
        verbose_name_plural = "Posts"

    title = models.CharField(max_length=255)
    content = models.TextField()
    tags = models.ManyToManyField(Tag, blank=True)

    def __str__(self):
        return self.title

Here is how my serializer (Tags, Posts) looks like:

class TagSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tag
        fields = '__all__'

    name = serializers.CharField(max_length=200)

    def create(self, validated_data):
        return Tag.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.name = validated_data.get('name', instance.name)
        instance.save()
        return instance

class PostSerializer(serializers.ModelSerializer):

    class Meta:
        model = Post
        fields = ('title', 'content', 'tags')

    title = serializers.CharField(max_length=250)
    content = serializers.CharField(max_length=1000)
    tags = serializers.PrimaryKeyRelatedField(many=True, queryset=Tag.objects.all())

    def create(self, validated_data):
        tags = validated_data.pop('tags')
        # [do i need to look for tags, create if not exists and retrieve the ids]

        post = Post.objects.create(**validated_data)
        for tg in tags:
            post.tags.add(tg)
        return post

    def update(self, instance, validated_data):
        instance.title = validated_data.get('title', instance.title)
        instance.content = validated_data.get('content', instance.content)

        tags = validated_data.pop('tags')

        # [do i need to check for tags, create if not exists and retrieve the ids]
        instance.save()
        return instance

So I wish to save the post details with tags such that it create the tags if not exists. As i am new to django and rest framework i am not sure if there is some out of the box functionality available to achieve this. Or do I need to write some code in my PostSerializer that manually creates new tags and return the ids, then save them with post model?

Let me know if you want further information

Thanks in advance

回答1:

I think you can use Django's get_or_create() method as,

def create(self, validated_data):
    tags = validated_data.pop('tags')
    post = Post.objects.create(**validated_data)
    for tag in tags:
        tag_obj, create = Tag.objects.get_or_create(name=tag)
        post.tags.add(tag_obj)
    return post

The get_or_create() method will return a tuple of (object, created), where object is the retrieved or created object and created is a boolean specifying whether a new object was created.