这是我的模特:
class Profile(models.Model):
user = models.OneToOneField(User)
phone = models.CharField(max_length=20, blank=True, null=True)
designation = models.CharField(max_length=50, blank=True, null=True)
roles = models.ManyToManyField(Role, related_name="profiles")
这是序列化器:
class UserSerializer(serializers.ModelSerializer):
email = serializers.EmailField(
required=True, validators=[UniqueValidator(queryset=User.objects.all())])
full_name = serializers.CharField(max_length=60, write_only=True)
phone = serializers.CharField(
max_length=20, allow_blank=True, required=False, write_only=True)
designation = serializers.CharField(
max_length=50, allow_blank=True, required=False, write_only=True)
roles = serializers.MultipleChoiceField(
choices=models.Role.objects.values_list('id', flat=True), write_only=True)
class Meta:
model = User
fields = ('id', 'email', 'full_name', 'phone', 'designation', 'roles')
问题
所有请求均以Content-Type: application/json
当我使用空有效负载发布请求时,DRF会引发400(必填字段不完整)
{
"full_name": [
"required"
],
"email": [
"required"
],
}
当POST请求正文为{}
时,DRF会引发400,包含所有必填字段
{
"full_name": [
"required"
],
"email": [
"required"
],
"roles": [
"required"
]
}
问题
如果请求正文为空,我如何确保DRF提出ParseError
?
已经尝试
allow_blank
和required
无效。APITestCase
测试时没有不一致。我可以通过ARC重现错误。解决方法
添加了一个自定义异常处理程序,用于检查:
request = context['request']
if request.content_type == 'application/json' and type(request.data) != dict:
return response.Response(
{'detail': 'Invalid body'}, status=status.HTTP_400_BAD_REQUEST)
当请求正文为空时,request.data为django.http.QueryDict
。这是我正在检查的。但是,我更倾向于在其原点引发此错误,而不是检查它产生的副作用。
答案 0 :(得分:1)
使用普通DRF功能似乎无法做到这一点。如果响应正文为空,request._parse()
方法不会调用任何解析器,它只会返回默认值{}
。
这意味着您无法换出解析器并在某些端点上获得所需的行为。
# request.py @ 301
if stream is None or media_type is None:
if media_type and not is_form_media_type(media_type):
empty_data = QueryDict('', encoding=self._request._encoding)
else:
empty_data = {}
empty_files = MultiValueDict()
return (empty_data, empty_files)
parser = self.negotiator.select_parser(self, self.parser
<强>买者强>
你想要的行为有点不寻常;我认为DRF正在正确处理事情,但我可以理解为什么你想要一个不同的行为。也许这是DRF gihub中功能请求的内容? &#34;解析时添加allow_empty_body
标志(默认为True)。
注意:在请求中,空请求正文合法。例如,您可以使用它们来触发对象(例如post /api/accounts/592/disable/
如果你想要完成这个,有一些选择,但它们都很尴尬,可能会以某种方式破坏。
#1 django中间件
您可以为django编写一个中间件类来检查post
和空体的传入请求,并手动返回错误。
#2 monkeypatch请求类
您可以在应用启动时使用您的DRF请求类覆盖_parse()
方法。
<强>其他强>
可能在序列化程序中做一些疯狂的事情,或者手动检查post(self, request, **kwargs)
方法是否有空请求,但它们都有点hacky。