ManyToManyField Serializer抛出"该字段必须是唯一的"错误

时间:2015-09-15 16:10:10

标签: django django-models django-rest-framework

我正在尝试在两个模型 - 作者和书籍之间创建多对多关系。我的用例是我应该能够使用数据库中已存在的作者向数据库添加新书。

models.py

"results" : [ 
    {
        "_id" : "awesome",
        "value" : {
            "count" : 98.0000000000000000
        }
    }

serializers.py

class Author(models.Model):    
    author_id = models.CharField(max_length=20, primary_key=True)
    name = models.CharField(blank=True, null=True)

    def __unicode__(self):
        return self.name

    class Meta:
        ordering = ('author_id',)

class Book(models.Model):    
    title = models.CharField(max_length=50, primary_key=True)
    authors = models.ManyToManyField(Author)

    def __unicode__(self):
        return self.title

    class Meta:
        ordering = ('title',)

让我们说我的作者表已经有一个作者:

1,George RR Martin

现在,如果我想要与现有作者一起添加新书,这是我使用httpie发送的请求:

  

http -j POST http://localhost/books title =" The Winds of Winter"作者:=' [{" AUTHOR_ID":" 1"}]'

当我这样做时,我收到了这个错误:

输出错误

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = ('author_id', 'name')


class BookSerializer(serializers.ModelSerializer):
    authors = AuthorSerializer(many=True)

    class Meta:
        model = Book
        fields = ('title', 'authors')

    def create(self, validated_data):
        book = Book.objects.create(name=validated_data['title'])

        for item in validated_data['authors']:
            author = Author.objects.get(author_id=item['author_id'])
            book.authors.add(author)

        return book

似乎正在调用AuthorSerializer,它会检查提供的 author_id 与数据库中的 author_id ,并抛出此错误。

对此有任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

您是否有必须使用自定义PK字段的具体原因?

Django automatically creates primary key fields for you。如果您只是从模型和序列化程序中删除该字段(并在数据库上创建/运行迁移),则不必在前端POST调用中指定pk,而Django将创建一个AutoField自动递增模型的id

class Author(models.Model):    
    # Remove this line and run makemigrations.
    # author_id = models.CharField(max_length=20, primary_key=True)
    name = models.CharField(blank=True, null=True)

    def __unicode__(self):
        return self.name

    class Meta:
        ordering = ('author_id',)

如果没有,请考虑使用models.AutoField而不是models.CharField作为主键字段,并且不要在POST来电中使用此字段。

请注意,如果您已经创建了一个大型数据库,则可能需要在迁移中执行一些复杂的工作,即this answer