如何序列化不是来自请求的数据并正确验证它(Django Rest框架中的ModelSerializer)?
使用Django Rest Framework 3、基于函数的视图和ModelSerializer(更具体地说是HyperlinkedModelSerializer) 当用户从客户端提交表单时,我有一个视图,它获取请求数据,使用它调用外部API,然后使用外部API中的数据填充模型序列化程序的数据。 我相信这部分工作正常,从我读到的内容来看,您应该使用上下文和验证() 在我的模型序列化程序中,到目前为止,我只有一个overidden函数:如何序列化不是来自请求的数据并正确验证它(Django Rest框架中的ModelSerializer)?,django,validation,serialization,django-rest-framework,Django,Validation,Serialization,Django Rest Framework,使用Django Rest Framework 3、基于函数的视图和ModelSerializer(更具体地说是HyperlinkedModelSerializer) 当用户从客户端提交表单时,我有一个视图,它获取请求数据,使用它调用外部API,然后使用外部API中的数据填充模型序列化程序的数据。 我相信这部分工作正常,从我读到的内容来看,您应该使用上下文和验证() 在我的模型序列化程序中,到目前为止,我只有一个overidden函数: from django.core.validators i
from django.core.validators import URLValidator
def validate(self, data):
if 'foo_url' in self.context:
data['foo_url'] = self.context['foo_url']
URLValidator(data['foo_url'])
if 'bar_url' in self.context:
data['bar_url'] = self.context['bar_url']
URLValidator(data['bar_url'])
return super(SomeSerializer, self).validate(data)
以防万一,相关视图代码如下所示:
context = {'request': request}
...
context['foo_url'] = foo_url
context['bar_url'] = bar_url
s = SomeSerializer(data=request.data, context=context)
if s.is_valid():
s.save(user=request.user)
return Response(s.data, status=status.HTTP_201_CREATED)
现在假设我有正确的想法(我的模型确实从相应的上下文数据中填充了foo\u url
和bar\u url
字段),我感到困惑的是验证是如何不起作用的。如果我给它错误的数据,模型序列化程序不会拒绝它
我假设在validate()
中,通过将上下文数据添加到数据中,当调用is\u validate()
时,将检查数据的有效性。可能不是这样,特别是当我打印出s
(在使用序列化程序之后,但在调用is\u valid()
之前)时,没有迹象表明请求对象的数据已由validate()
中的上下文数据填充(我不知道是否应该填充)
因此,我尝试在validate()
方法中直接调用URLvalidator,但似乎仍然不起作用。尽管提供了无效数据,如“asdf”或空python dict({}),但没有错误。我的测试断言表明,该字段确实包含像“{}”这样的无效数据
正确的方法是什么?您没有调用验证器
通过执行URLValidator(data['bar\u url'])
您实际上是在使用自定义方案构建url验证程序,仅此而已。正确的代码应为:
URLValidator()(data['bar_url'])
在这里,您构建一个默认url验证程序,然后验证该值
但无论如何,我不会使用这种方法,而是直接添加额外的数据(不使用上下文),并让DRF通过声明正确的字段来进行验证:
# Somewhere in your view
request.data['bar_url'] = 'some_url'
# In serializer:
class MySerializer(serializers.ModelSerializer):
bar_url = serializers.URLField()
class Meta:
fields = ('bar_url', ...)
回答你的评论
我也不明白这是怎么让它过去的
Django模型验证
看看这个答案:
默认情况下,Django不会自动调用.full\u clean
方法,这样您就可以用无效值保存模型实例(除非约束在数据库级别)。我也不明白这是如何通过Django的模型验证的,因为'asdf'或'{}'不是有效的URLField数据。非常感谢,似乎我误读了文档。我认为在调用is_valid()之前,request.data是不可访问的(有点像Django表单数据)。我假设Django在验证之前出于某种原因使其表单数据不可变。像这样编辑请求数据一般可以吗?好的,我们解释了请求不可变的原因。我个人认为这样向请求添加数据是可以的,这样序列化过程就可以保持不变。