Django rest框架发布空日期字段错误

x0fgdtte  于 2023-03-09  发布在  Go
关注(0)|答案(5)|浏览(184)

model.py

class Form(models.Model):
    no = models.IntegerField()
    finish_date = models.DateField(blank=True, null=True)

serializers.py

class FormSerializer(serializers.ModelSerializer):
    class Meta:
        model = Form
        fields = '__all__'

如果我尝试:

http http://127.0.0.1:8000/api/forms no=112 "finish_date"=""

它返回错误:

"finish_date": [
    "Date has wrong format. Use one of these formats instead: YYYY[-MM[-DD]]."
]

如果我将“finish_date”设置为空,这篇文章就可以工作,而且StringField(blank=True, null=True)不会得到错误。
如何解决?

fxnxkyjh

fxnxkyjh1#

问题是DateTimeField当前不支持allow_blank关键字参数。
但是它支持allow_null,因此您有两个选择:
1.发送前清理数据
擦除"finish_date": ""-〉"finish_date": null**然后 * 发送到服务器
如果您使用JavaScript提交表单,可能需要执行以下操作:

if (data["finish_date"] == "") {
    data["finish_date"] = null;
}

1.接收后清理数据
在串行化器中擦除"finish_date": ""-〉"finish_date": None
您可以在ModelSerializer上使用.to_internal_value()方法轻松完成此操作

class FormSerializer(serializers.ModelSerializer):
    class Meta:
        model = Form
        fields = '__all__'

    def to_internal_value(self, data):
        # check for "finish_date": "" and convert to None
        # This must be done before .validate()
        if data['finish_date'] == '':
            data['finish_date'] = None
        return super(FormSerializer, self).to_internal_value(data)

.to_internal_value()方法在Django Rest Framework Fields API Reference中被大量提及

rggaifut

rggaifut2#

现在,在上面的模型中,您有一个DateField,并且DateField接受某些格式,这些格式类似于您发布的错误中显示的格式。

http http://127.0.0.1:8000/api/forms no=112 "finish_date"=""

您实际上是将一个空字符串(“”)传递给序列化程序,这不是DateField的有效格式。请尝试不传递“finish_date”参数的Post,我认为它会工作。或者,您可以传递过去的某个默认日期,而不是传递空字符串。

ao218c7q

ao218c7q3#

使用以下代码修改序列化程序

class FormSerializer(serializers.ModelSerializer):

finish_date = serializers.DateTimeField(allow_null=True)

class Meta:
    model = Form
    fields = '__all__'
zi8p0yeb

zi8p0yeb4#

ver. 3x开始,DJango Rest Framework不提供允许空值的DateField,您不必在有效负载中发送字段或显式设置null作为字段值,但您不能设置""空值。
为了解决这个问题,我实现了我自己的自定义字段,它是在DRF DateField之上构建的,因此您不必担心对现有要求的妥协!)

# sample.py

from rest_framework import serializers

class DateField(serializers.DateField):
    """
    Date field which allows blank values.

    As of djangorestframework 3x, DRF does not provide a date field which
    allows blank ("") values, so this field is built on top of DRF DateField
    which provides functionality to accept blank values.
    """

    allow_blank = None

    def __init__(self, *args, **kwargs):
        self.allow_blank = kwargs.pop("allow_blank", False)
        super().__init__(format, *args, **kwargs)

    def to_internal_value(self, data):
        # calc length if blank values are allowed,
        # this improves performance a bit 
        if self.allow_blank:
            if len(data) == 0:
                return data
        return super().to_internal_value(data)
    
    def to_representation(self, value):
        # DRF by default returns None if no value is set
        # so no custom implementation is required
        return super().to_representation(value)

用法:

from sample import DateField

my_date_field = DateField(
    allow_blank=True,
)
kmpatx3s

kmpatx3s5#

如果有人遇到此问题并使用javascript客户端发布数据,请尝试将undefined作为空白日期发送

相关问题