何时使用序列化器的create()和ModelViewset的create()perform_create() [英] When to use Serializer's create() and ModelViewset's create() perform_create()
问题描述
我想澄清有关创建模型对象的 django-rest-framework
的给定文档。到目前为止,我发现有3种方法来处理此类事件。
I want to clarify the given documentation of django-rest-framework
regarding the creation of a model object. So far I found that there are 3 approaches on how to handle such events.
-
Serializer的
create ()
方法。这是文档
class CommentSerializer(serializers.Serializer):
def create(self, validated_data):
return Comment.objects.create(**validated_data)
ModelViewset create()
方法。 文档
class AccountViewSet(viewsets.ModelViewSet):
queryset = Account.objects.all()
serializer_class = AccountSerializer
permission_classes = [IsAccountAdminOrReadOnly]
ModelViewset perform_create()
方法。 文档
class SnippetViewSet(viewsets.ModelViewSet):
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
这三种方法很重要,具体取决于您的应用程序环境。
These three approaches are important depending on your application environment.
但是什么时候我们需要使用每个 create()/ perform_create()
函数??。另一方面,我发现有人要求为单个发布请求调用两个create方法,即modelviewset的 create()
和序列化程序的 create()
。
But WHEN do we need to use each create() / perform_create()
function??. On the other hand I found some account that two create methods were called for a single post request the modelviewset's create()
and serializer's create()
.
希望任何人都可以分享他们的一些知识来进行解释,这肯定会对我的开发过程有所帮助。
Hopefully anyone would share some of their knowledge to explain and this will surely be very helpful in my development process.
推荐答案
- 您将使用
create(self,validated_data)
在将AND prod值保存到每个模型字段之前,向对象添加任何其他详细信息,就像** validated_data
一样。理想情况下,您只想在一个位置执行这种探测形式,因此您的CommentSerializer
中的create
方法是最好的地方。最重要的是,您可能还想调用外部api,以在将帐户保存到自己的数据库之前在其旁边创建用户帐户。您应该将此create
函数与ModelViewSet
结合使用。总是思考-精简视图,厚序列化程序。
- You would use
create(self, validated_data)
to add any extra details into the object before saving AND "prod" values into each model field just like**validated_data
does. Ideally speaking, you want to do this form of "prodding" only in ONE location so thecreate
method in yourCommentSerializer
is the best place. On top of this, you might want to also call external apis to create user accounts on their side just before saving your accounts into your own database. You should use thiscreate
function in conjunction withModelViewSet
. Always think - "Thin views, Thick serializers".
示例:
def create(self, validated_data):
email = validated_data.get("email", None)
validated.pop("email")
# Now you have a clean valid email string
# You might want to call an external API or modify another table
# (eg. keep track of number of accounts registered.) or even
# make changes to the email format.
# Once you are done, create the instance with the validated data
return models.YourModel.objects.create(email=email, **validated_data)
-
create(self,request,*
函数在ModelViewSet
中的args,** kwargs)CreateModelMixin
类中定义是ModelViewSet
的父级。CreateModelMixin
的主要功能是:
The
create(self, request, *args, **kwargs)
function in theModelViewSet
is defined in theCreateModelMixin
class which is the parent ofModelViewSet
.CreateModelMixin
's main functions are these:
from rest_framework import status
from rest_framework.response import Response
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def perform_create(self, serializer):
serializer.save()
如您所见,上面的 create
函数负责在序列化程序上调用验证并产生正确的响应。这样做的好处是,您现在可以隔离应用程序逻辑,而不必担心平凡和重复的验证调用以及处理响应输出:)。与序列化程序中的 create(self,validated_data)
(您的特定应用程序逻辑所在的位置)结合使用时,效果很好。
As you can see, the above create
function takes care of calling validation on your serializer and producing the correct response. The beauty behind this, is that you can now isolate your application logic and NOT concern yourself about the mundane and repetitive validation calls and handling response output :). This works quite well in conjuction with the create(self, validated_data)
found in the serializer (where your specific application logic might reside).
- 现在您可能会问,为什么我们要有一个单独的
perform_create(self,serializer)
函数,只需一行代码!!!?好吧,这背后的主要原因是在调用save
函数时允许自定义。您可能需要在调用save
之前提供额外的数据(例如serializer.save(owner = self.request.user)
,如果我们没有perform_create(self,serializer)
,则必须覆盖create(self,请求,* args,** kwargs)
,这恰恰违背了让mixins进行繁重而无聊的工作的目的。
- Now you might ask, why do we have a separate
perform_create(self, serializer)
function with just one line of code!?!? Well, the main reason behind this is to allow customizeability when calling thesave
function. You might want to supply extra data before callingsave
(likeserializer.save(owner=self.request.user)
and if we didn't haveperform_create(self, serializer)
, you would have to override thecreate(self, request, *args, **kwargs)
and that just defeats the purpose of having mixins doing the heavy and boring work.
希望这会有所帮助!
这篇关于何时使用序列化器的create()和ModelViewset的create()perform_create()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!