使用Django Rest
作为后端在做的项目中,Model
是这样的:
class Sample(models.Model): ... creater = models.ForeignKey(User, on_delete=models.CASCADE) ...
Serializers
是这样:
class SampleSerializer(serializers.ModelSerializer): class Meta: model = Sample fields = (...,'creater')
Views
是这样:
class SampleList(generics.ListCreateAPIView): queryset = Sample.objects.all() serializer_class = SampleSerializer permission_classes = (IsOwnerOrReadOnly,) def perform_create(self, serializer): ... serializer.save(creater=self.request.user,...)
问题是,我在执行插入的时候,总是提示:
{"creater": ["This field is required."]}
百思不得其解,因为明明通过creater=self.request.user
赋值了啊。
后来在Model
中,将creater
字段修改为
creater = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
问题解决。
但这是为什么呢?谷歌后发现:
The perform_create method is called by your View's create method after serializer validation. At this stage, DRF will have found and flagged the missing user field.
原来视图中的perform_create操作晚于serializer的校验。上面的代码中,perform_create前DRF已经发现creater字段的缺失。
来看看rest_framework
的源码:
class CreateModelMixin(object): """ Create a model instance. """ 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() def get_success_headers(self, data): try: return {'Location': str(data[api_settings.URL_FIELD_NAME])} except (TypeError, KeyError): return {}
解决这个问题的方法有多种,除了上面的null=True, blank=True
之外,还可以:
serializer
中设置这个字段readonly=True
,或serializer
中重载validate_user
,或currentuserdefault
校验器。参考地址。
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句