最初创建对象时,我使用当前登录的用户分配模型字段“owner”。
模型:
class Account(models.Model):
id = models.AutoField(primary_key=True)
owner = models.ForeignKey(User)
name = models.CharField(max_length=32, unique=True)
description = models.CharField(max_length=250, blank=True)
要设置所有者的序列化程序:
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = models.Account
fields = ('name', 'description')
def restore_object(self, attrs, instance=None):
instance = super().restore_object(attrs, instance)
request = self.context.get('request', None)
setattr(instance, 'owner', request.user)
return instance
系统中的其他用户可以更新另一个帐户对象,但所有权应保留在原始用户手中。显然,上面的内容打破了这一点,因为在使用当前登录的用户进行更新时,所有权将被覆盖。
所以我把它更新成这样:
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = models.Account
fields = ('name', 'description')
def restore_object(self, attrs, instance=None):
new_instance = False
if not instance:
new_instance = True
instance = super().restore_object(attrs, instance)
# Only set the owner if this is a new instance
if new_instance:
request = self.context.get('request', None)
setattr(instance, 'owner', request.user)
return instance
这是推荐的做这种事情的方法吗?我看不出别的办法,但到目前为止我的经验非常有限。
谢谢
从评论@zaphod100.10的答案开始。或者,在视图代码中(删除了上述序列化程序中的自定义restore_object方法):
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.DATA, files=request.FILES)
if serializer.is_valid():
serializer.object.owner = request.user
self.pre_save(serializer.object)
self.object = serializer.save(force_insert=True)
self.post_save(self.object, created=True)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED,
headers=headers)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
这里应该划分责任,因为序列化器/视图只接收/清理数据并确保提供了所有需要的数据,那么相应地设置owner字段应该是模型的责任。将这两个目标分开是很重要的,因为模型可能会从其他地方更新(比如从管理表单)。
视图.py
模型.py
基本上,您希望在创建时设置所有者,而不是在后续更新时设置所有者。为此,我认为你应该在后视图中设置所有者。我认为这样更合乎逻辑,更有力。更新是通过PUT视图完成的,因此您的数据应该始终正确,因为在更新时,如果所有者在PUT上不可编辑,则无法更改所有者。
为了创建视图,您可以使用DRF的基于类的通用视图。按原样使用RetrieveUpdateDeleteView。For ListCreateView重写post方法。使用django模型表单验证数据并创建帐户实例。
您必须复制request.DATA dict并插入“owner”作为当前用户。
POST方法的代码可以是:
使用
pre_save
的潜在其他选项,我认为它似乎只用于此类事情。我认为这是pre_save的目的,它非常简洁。
相关问题 更多 >
编程相关推荐