来自 url 的 DRF 嵌套路由器序列化器源字段
DRF nested router serializer source fields from url
我有作者和书籍模型。一个作者有很多书
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)
在我的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)
在我的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},
}
在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)
由于书籍与作者相关并且我正在使用嵌套路由器,因此 curl 调用看起来像
curl --location --request POST 'localhost:8000/author/1/book' --data '{"name": "Book Name"}'
在我的 BookViewSet
中,我最终在调用序列化程序 is_valid
方法之前手动将 author_pk 添加到数据对象。有没有一种方法可以从 URL 路由指定源或任何更好的方法?
在这种情况下,您可以将 author_pk
传递给 save()
以自动设置新创建图书的作者 ID,如 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)
我有作者和书籍模型。一个作者有很多书
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)
在我的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)
在我的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},
}
在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)
由于书籍与作者相关并且我正在使用嵌套路由器,因此 curl 调用看起来像
curl --location --request POST 'localhost:8000/author/1/book' --data '{"name": "Book Name"}'
在我的 BookViewSet
中,我最终在调用序列化程序 is_valid
方法之前手动将 author_pk 添加到数据对象。有没有一种方法可以从 URL 路由指定源或任何更好的方法?
在这种情况下,您可以将 author_pk
传递给 save()
以自动设置新创建图书的作者 ID,如 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)