Reputation: 1154
I have an author and books model. An author has many books with him
class Author(Model):
id = UUIDField(primary_key=True, default=uuid4, editable=False)
name = CharField(max_length=50)
email = CharField(max_length=50)
class Book(Model):
id = UUIDField(primary_key=True, default=uuid4, editable=False)
name = CharField(max_length=50)
author = ForeignKey(Author, on_delete=models.CASCADE)
In my urls.py
author_router = SimpleRouter()
author_router.register(
r"author", AuthorViewSet, basename=author
)
nested_author_router = NestedSimpleRouter(author_router, r"author", lookup="author")
nested_author_router.register(r"book", BookViewSet)
In my searlizers.py
class BookSerializer(ModelSerializer):
class Meta:
model = Book
fields = (
"id",
"name",
"author",
)
extra_kwargs = {
"id": {"required": False},
"author": {"required": False},
}
class AuthorSerialzer(ModelSerializer):
class Meta:
model = Author
fields = (
"id",
"name",
"email",
)
extra_kwargs = {
"id": {"required": False},
}
In views.py
class BookViewSet(GenericViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
def create(self, request, author_pk):
data = request.data
data["author"] = author_pk
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
Since books are related to the author and I am using nested routers the curl call would look like
curl --location --request POST 'localhost:8000/author/1/book' --data '{"name": "Book Name"}'
In my BookViewSet
I end up manually adding the author_pk to the data object before calling serializer is_valid
method. Is there a way to specify the source from URL route or any better way of doing this?
Upvotes: 1
Views: 818
Reputation: 12068
In this case you can pass the author_pk
to save()
to automatically set the author id of the newly created book, as explained here
:
def create(self, request, author_pk):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(author_id=author_pk)
return Response(serializer.data)
Upvotes: 1