Django Rest Framework:手动填充字段的最佳方法
考虑以下模型:
class Request(models.Model):
user = models.ForeignKey('User', related_name='requests')
还有一个包含创建和更新功能的视图集:
class RequestViewSet(mixins.CreateModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet):
我想在创建时设置用户,但在更新时不设置用户。
第一个解决方案:
class RequestViewSet(mixins.CreateModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet):
def pre_save(self, obj):
create = False
try:
if not obj.user:
create = True
except ObjectDoesNotExist:
create = True
if create:
obj.user = self.request.user
第二个解决方案使用了 restore_object:
class RequestSerializer(serializers.ModelSerializer):
def restore_object(self, attrs, instance=None):
create = not instance
instance = super(RequestSerializer, self).restore_object(attrs, instance)
if create:
request = self.context['request']
instance.user = request.user
return instance
哪个更合逻辑呢?我倾向于选择第一个(除了 try/except 之外,我找不到其他替代方案)。
1 个回答
1
我不是很喜欢基于类的视图,我更喜欢模型比较复杂,而视图比较简单。
我会选择在请求(Request)上使用一个post_save信号,并检查创建的参数。
https://docs.djangoproject.com/en/dev/ref/signals/#post-save
Request(...):
@classmethod
def post_save(cls, sender, instance, created, raw, **kwargs):
if raw:
return
if created:
pass # do your on create stuff here
post_save.connect(Request.post_save, sender=Request, dispatch_uid="uniqueid") # use weak=False if you use a local function
另外要注意的是,instance.save()会再次触发保存信号,所以如果你想避免再次处理所有信号(或者更糟糕的是,产生信号循环 ;-)),你可以考虑直接使用.update()。