假设我有一个视图,我需要在调用serializer.save之前检查是否有字段,以确保我没有收到字典键错误:
class BarView(CreateAPIView):
serializer_class = BarSerializer
queryset = Bar.objects.all()
def perform_create(self, serializer):
if 'foo' not in self.request.data:
raise ParseError('foo field required.')
foo = get_object_or_404(Foo, pk=self.request.data['foo'])
if foo.counter == 10:
raise ParseError('foo limit reached.')
return serializer.save(user=self.request.user, foo=foo)
而不是返回“foo field required”。我想返回一条与Django REST返回相同的消息,例如: {“foo”:[“此字段为必填项。”]}
有更好的方法吗?也许用串行器单独验证foo字段?
更新:我忘了提及用户字段也是必需的。
Bar的模型是:
class Bar(models.Model):
user = models.ForeignKey(User, db_index=True, editable=False)
foo = models.ForeignKey(Foo, db_index=True)
答案 0 :(得分:3)
是,
只需查看文档:{{3}}
(我认为字段foo
是Bar
模型的一部分,如果不是,请将其添加到fields
中的Meta
:< / p>
向BarSerializer添加验证:
class BarSerializer(serializers.ModelSerializer):
def validate_foo(self, value):
if not value:
raise serializers.ValidationError("foo field required.")
if Foo.objects.filter(pk=value, counter__gte=10).exists():
raise serializers.ValidationError("foo limit reached.")
return value
class Meta:
model = Bar
然后通过扩展这个来创建你的视图:
from rest_framework.exceptions import ValidationError
class MyCreateAPIView(CreateAPIView):
def post(self, request, *args, **kwargs):
try:
return super(BarView, self).post(request, *args, **kwargs)
except ValidationError as e:
return Response(e.detail, , status=status.HTTP_400_BAD_REQUEST)
def create(self,request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
try:
self.perform_create(serializer)
except DjangoValidationError as e:
raise ValidationError(e.messages)
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(serializer):
# do your stuff
serializer.save()
答案 1 :(得分:1)
是的,执行此操作的最佳方法是使用foo
类中的extra_kwargs
选项在序列化程序中生成Meta
字段。
DRF将自动为您处理验证。您不需要自己提出此验证错误。
class Meta:
...
extra_kwargs = {'foo': {'required':True}} # make 'foo' a required field.
现在,只要foo
中未传递request
字段,foo
字典中就会有一个键serializer.errors
,其值为{{1 }}
另外,创建一个This field is required.
函数,该函数将验证validate_foo()
的限制。
foo_object.counter
最终代码:
<强> serializers.py 强>
def validate_foo(self, value):
self.foo_object = get_object_or_404(Foo, pk=value) # get the 'foo' object
if self.foo_object.counter == 10: # check for limits
raise serializers.ValidationError('foo limit reached.') # raise error
return value # must return the value at the end
<强> views.py 强>
在您的观看中,您需要覆盖class BarSerializer(serializers.ModelSerializer):
class Meta:
...
extra_kwargs = {'foo': {'required':True}} # make 'foo' a required field.
def validate_foo(self, value):
self.foo_object = get_object_or_404(Foo, pk=value)
if self.foo_object.counter == 10:
raise serializers.ValidationError('foo limit reached.')
return value
并将perform_create()
和user
传递给serializer.foo_object
函数。
serializer.save()
答案 2 :(得分:0)
您可以使用用户定义的消息
返回Response
if 'foo' not in self.request.data:
return Response({"foo":["This field is required."]})