How to use serializer to create a new object with

2019-08-09 05:36发布

问题:

suppose this model:

class Tweek(models.Model):
    content = models.CharField(max_length=140)
    date = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(User, related_name='author')

    class Meta:
        ordering = ['-date']

    def __unicode__(self):
        return self.content

Everthing works fine, now i try to bind a rest api uppon. I've installed the django rest framework and I can retrieve tweeks but I cannot create new ones.

I have this serializer for the Tweek model:

class TweekSerializer(serializers.ModelSerializer):
    author = UserSerializer()

    class Meta:
        model = Tweek
        fields = ('content', 'date', 'author')

    def create(self, validated_data):
        author_data = validated_data.pop('author')
        author = User.objects.get(username=author_data)

        return Tweek.objects.create(author=author, **validated_data)

and the user serializer somply looks like:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name')

but the post returns

{
    "author": {
        "username": [
            "This field must be unique."
        ]
    }
}

I've followed the doc, but i'm lost with this case :( Any idea ?

回答1:

The issue here is that any field with unique=True set, like the username field on the Django User model, will automatically have the UniqueValidator added to the serializer field. This validator is what is triggering the message you are seeing, and you can remove the validation by setting validators to [] (an empty list) when initializing the field.

The other issue that you are going to run into is that you are trying to create an object with a foreign key, but you are returning the full serialized object in your response. This issue is easier fixed by using a second field for setting the id, that is write-only, and using the original serializer field for the nested representation and making that read-only.

You can find more information in the following Stack Overflow question: DRF: Simple foreign key assignment with nested serializers?