简体   繁体   中英

Django REST Framework relationship serialization

I've been banging my head against this issue and know I have to be missing something simple.

I'm trying to learn Django REST Framework and having issues setting the foreign keys of a new object to existing other objects when POSTing JSON to the server.

models.py

class Genre(models.Model):
    name = models.CharField(max_length=200)

class Author(models.Model):
    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)

    def full_name(self):
        return self.first_name + ' ' + self.last_name

class Book(models.Model):
    title = models.CharField(max_length=200)
    genre = models.ForeignKey(Genre)
    isbn = models.CharField(max_length=15, default='')
    summary = models.CharField(max_length=500, null=True)
    author = models.ForeignKey(Author)

serializers.py

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = ('id', 'first_name', 'last_name',)


class GenreSerializer(serializers.ModelSerializer):
    class Meta:
        model = Genre
        fields = ('id', 'name',)


class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer(read_only=True)
    genre = GenreSerializer(read_only=True)

    class Meta:
        model = Book
        fields = ('id','url', 'author', 'genre', 'title', 'isbn', 'summary',)

What I'm trying to is create a new book related to an existing Author and Genre . So, given some JSON like

{"title": "Title", 
 "author": {"id":1}
 "genre" : {"id":2}
 ...
}

I want to create a new book and have its Genre and Author set to the appropriate entities that are already in the database.

I've tried to change the author and genre fields on BookSerializer to serializers.PrimaryKeyRelatedField() and scoured the docs and SO for answers, including this one . I've tried to change the fields in the JSON to "author": 1 or "genre_id": 2 but I can't seem to get it working. I keep getting django.db.utils.IntegrityError: books_book.genre_id may not be NULL .

I am using a DRF ModelViewSet for the views if that makes a difference.

What am I missing here?

You are getting Integrity error because it's expecting the author instance but you are sending the pk related to author. Try this

serializers.py

class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer(read_only=True)
    genre = GenreSerializer(read_only=True)

    class Meta:
        model = Book
        fields = ('id','url', 'author', 'genre', 'title', 'isbn', 'summary',)

    def create(self, validated_data):
        author_id = self.initial_data.pop("author")
        genre_id = self.initial_data.pop("genre")
        author = Author.objects.get(id=author_id)
        genre = Genre.objects.get(id=genre_id)
        book = Book.objects.create(author=author, genre=genre, **validated_data)
        return book

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM