Ash*_*mar 4 django python-3.x django-rest-framework
在使用序列化程序在django rest框架上制作api时,我感到困惑,请告诉我save(),create()和update()方法之间的确切区别,我的代码示例如下,
View.py
class AddUser(views.APIView):
serializer_class = UserForAdminSerializer
def post(self, request, *args, **kwargs):
serializer = UserForAdminSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Run Code Online (Sandbox Code Playgroud)
serializers.py
class UserForAdminSerializer(serializers.ModelSerializer):
first_name = serializers.CharField(max_length=30)
last_name = serializers.CharField(max_length=30)
name = serializers.CharField(max_length=30)
password = serializers.CharField(max_length=20, style={'input_type': 'password'})
class Meta:
model = User
fields = ('id', 'url', 'first_name', 'last_name', 'name', 'username', 'email', 'password',
'total_exp_year', 'total_exp_month', 'voteup_count', 'is_featured',
'is_active', 'headline', 'description', 'profile_picture', )
def create(self, validated_data):
password = validated_data.pop('password', None)
instance = self.Meta.model(**validated_data)
if password is not None:
instance.set_password(password)
instance.save()
return instance
Run Code Online (Sandbox Code Playgroud)
在view.py文件中的上述代码上,我使用了save()方法和serializers.py使用了save()或update()方法,因此请向我解释它的工作方式,并消除我在save()和create()之间的困惑
通常,对代码有个很好的了解的最好方法是实际阅读它,所以让我们看一下源代码:
class BaseSerializer(Field):
...
def update(self, instance, validated_data):
raise NotImplementedError('`update()` must be implemented.')
def create(self, validated_data):
raise NotImplementedError('`create()` must be implemented.')
def save(self, **kwargs):
...
... a lot of assertions and safety checks ...
...
validated_data = dict(
list(self.validated_data.items()) +
list(kwargs.items())
)
if self.instance is not None:
self.instance = self.update(self.instance, validated_data)
....
else:
self.instance = self.create(validated_data)
...
return self.instance
Run Code Online (Sandbox Code Playgroud)
好了,所以,在该基类的方法update和create被留到具体子类被实现(作为细节将用于串行如变化ListSerializer或ModelSerializer)。
但是,save 已实现,它基本上只是检查对象是新对象还是现有对象(if self.instance is not None)和分别调用update或create。此代码将在其他所有序列化器中调用。
让我们看一下具体的子类:
def create(self, validated_data):
...
... some stuff happening
...
try:
# Here is the important part! Creating new object!
instance = ModelClass.objects.create(**validated_data)
except TypeError:
raise TypeError(msg)
# Save many-to-many relationships after the instance is created.
if many_to_many:
for field_name, value in many_to_many.items():
set_many(instance, field_name, value)
return instance
def update(self, instance, validated_data):
raise_errors_on_nested_writes('update', self, validated_data)
info = model_meta.get_field_info(instance)
# Simply set each attribute on the instance, and then save it.
# Note that unlike `.create()` we don't need to treat many-to-many
# relationships as being a special case. During updates we already
# have an instance pk for the relationships to be associated with.
for attr, value in validated_data.items():
if attr in info.relations and info.relations[attr].to_many:
set_many(instance, attr, value)
else:
setattr(instance, attr, value)
instance.save()
return instance
Run Code Online (Sandbox Code Playgroud)
正如您所看到的create和update调用set_many(instance, attr, value)以设置对象属性的值。然而,create确实一个关键的呼叫前:ModelClass.objects.create(**validated_data)。这实际上创建了新实例。
我希望这可以清除它。
在Django Rest Framework 文档中,他们非常清楚地说明了何时覆盖保存方法和何时创建方法。
为了方便起见,我在这里发布他们的解释
在某些情况下,.create()和.update()方法名称可能没有意义。例如,在联系表格中,我们可能没有创建新实例,而是发送了电子邮件或其他消息。在这些情况下,您可能会选择直接重写.save(),因为它更具可读性和意义。
例:-
class ContactForm(serializers.Serializer):
email = serializers.EmailField()
message = serializers.CharField()
def save(self):
email = self.validated_data['email']
message = self.validated_data['message']
send_email(from=email, message=message)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5308 次 |
| 最近记录: |