我遇到了django休息框架的问题
我的前面是将数据发布到drf,其中一个字段可能是null
或空字符串""
。
# models.py
class Book(models.Model):
title = models.CharField(max_length=100)
publication_time = models.TimeField(null=True, blank=True)
# serializers.py
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ('id', 'title', 'publication_time')
publication_time
可以是blank
或""
。
空白案例有效,事实上当我发布json {"title": "yeah a book", "publication_time": none}
时,一切都很好。
当我发送{"title": "yeah a book", "publication_time":""}
时,我收到了验证错误"Time has wrong format. Use one of these formats instead: hh:mm[:ss[.uuuuuu]]."
我尝试将字段验证器添加到序列化程序类:
def validate_publication_time(self, value):
if not value:
return None
甚至使用extra_kwargs
# ....
def empty_string_to_none(value):
if not value:
return None
# ....
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ('id', 'title', 'publication_time')
extra_kwargs = {'publication_time': {'validators' : [empty_string_to_none]} }
我要做的是在发生任何验证之前将空字符串转换为None(应该由序列化程序和模型接受)或作为第一个验证规则。
问题:
问题是validate_publication_time
永远不会被调用,甚至在击中函数之前我都会收到验证错误。因为我understood有一个特定的顺序,验证器运行,但现在我不知道如何解决我的问题。
问题:
我想要做的是实际清理数据,以便在运行任何验证之前将""
转换为None
。可能吗?怎么样?
修改 这是我的序列化器的代表:
# from myapp.serializers import BookSerializer
# serializer = BookSerializer()
# print repr(serializer)
# This is the print result:
BookSerializer():
id = IntegerField(label='ID', read_only=True)
title = CharField(max_length=100)
publication_time = TimeField(allow_null=True, required=False)
因为你可以看到publication_time字段可以为null,不是吗?
答案 0 :(得分:3)
我遇到了同样的问题,最后找到了解决方案。
为了在错误发生之前处理''
,您需要覆盖to_internal_value
方法:
class BookSerializer(serializers.ModelSerializer)::
def to_internal_value(self, data):
if data.get('publication_time', None) == '':
data.pop('publication_time')
return super(BookSerializer, self).to_internal_value(data)
答案 1 :(得分:2)
你试过override serialization behavior吗?您需要的是覆盖.to_internal_value(self, data)
答案 2 :(得分:1)
您可以覆盖序列化程序的save
方法,您可以检查该值是否为空字符串,如果是,则将其设置为Null。
在序列化程序中(未经测试):
def save(self, *args, **kwargs)
if self.publication_time == "":
self.publication_time = Null
super.save(*args, **kwargs)
或者,您可以在视图中执行此操作(这是我的方式):
def perform_update(self, serializer):
publication_time = self.kwargs['publication_time']
if publication_time == "":
publication_time = Null
serializer.save(publication_time=publication_time)
只有这样你才需要覆盖perform_create,如果你在POST时也需要这样做,不仅仅是当PUT
答案 3 :(得分:0)
publication_time
是TimeField
,因此您不能指望将空字符串""
保存到其中。你得到错误是因为你只是想这样做。
当您通过"publication_time": none
时,一切正常,因为none
在那里被视为NULL
值,并且由于您设置了null=True
,因此不会抛出任何验证错误。
您对验证运行的顺序也是正确的。如果您创建了方法validate_publication_time
,则在这种情况下它永远不会运行,因为空字符串与TimeField
指定的格式不匹配,并且仅在该验证中引发错误。
答案 4 :(得分:0)
kwarg
是allow_null
而allow_blank
不是null
和blank
。