So I have 3 models of interest:
models.py
class Author(models.Model): #Author of books
name = models.CharField(max_length = 100)
@property # This is code to get the books linked to an author
def books(self):
book = Book.objects.filter(authors = self.id)
return ', '.join(map(str,book)) #This makes the book list in this format "A, B, C"
def __str__(self):
return self.name.title()
class Genre(models.Model): #Genre of books
name = models.CharField(max_length = 50, unique = True)
@property
def books(self):
book = Book.objects.filter(genre = self.id)
return ', '.join(map(str,book))
def __str__(self):
return self.name.title()
class Book(models.Model):
name = models.CharField(max_length = 150,) #Name of books
authors = models.ManyToManyField(Author,) #Many to many because multiple books can have multiple authors
genre = models.ManyToManyField(Genre)
def __str__(self):
return self.name.title()
Those are the models, and both genre and author have a many to many relation with books
serializers.py
class AuthorListSerializer(serializers.ModelSerializer):
class Meta:
model = models.Author
fields = ('name',)
class GenreListSerializer(serializers.ModelSerializer):
class Meta:
model = models.Genre
fields = ('name',)
class BookListSerializer(serializers.ModelSerializer):
authors = AuthorListSerializer(many = True,) #To represent the relationship as a string instead of id
genre = serializers.SlugRelatedField(many = True, queryset = models.Genre.objects.all(),slug_field = 'name')
class Meta:
model = models.Book
fields = ('name','authors','rating', 'genre')
class BookDetailSerializer(serializers.ModelSerializer):
publisher = serializers.SlugRelatedField(queryset = models.Publisher.objects.all(), slug_field= 'name') #To display publisher name instead of id
authors = serializers.StringRelatedField(many = True,) #To represent the relationship as a string instead of id
genre = serializers.StringRelatedField(many = True,)
class Meta:
model = models.Book
fields = ('name', 'authors', 'rating','genre',
'publisher', 'total_qty', 'avail_qty',
'pub_date','isbn','price',)
So in my Django-Rest-Framework Browsable api, Normal ForeignKey fields have their options displayed to create a new object instance. For example The publishers in the "BookDetailSerializer" have all the publishers displayed as options for a POST or PUT or PATCH request. but for the many to many fields that include Genre and Author it is not only blank, but it appears that I cannot put any input whatsoever. I have tried using the DRF-writable-nested third party package but nothing changed:
class BookListSerializer(WritableNestedModelSerializer):
authors = AuthorListSerializer(many = True,) #To represent the relationship as a string instead of id
genre = serializers.SlugRelatedField(many = True,
queryset = models.Genre.objects.all(),slug_field = 'name')
My question is how can I be able to make POST request with my list of Authors and Genres available through the DRF browsable api? Thanks in advance!!
This image shows the options available for making a POST request involving publishers
Update: So I have added a create method and it still doesn't work, as shown below:
class BookListSerializer(serializers.ModelSerializer):
authors = AuthorListSerializer(many = True,) #To represent the relationship as a string instead of id
genre = serializers.SlugRelatedField(many = True,
queryset = models.Genre.objects.all(),slug_field = 'name')
class Meta:
model = models.Book
fields = ('name','authors','rating', 'genre')
def create(self,validated_data):
authors_data = models.Author.objects.all()
book = Book.objects.create(authors = authors_data,**validated_data,)
return book
What can I do?