带Django REST Framework的不需要的字段错误

时间:2015-11-12 01:34:09

标签: python django rest django-rest-framework

我使用Django REST Framework在我的数据库/ Django模型上运行CRUD进程。我存储客户端数据的模型非常简单,只有一个字段导致我出现问题:CharField用于存储自定义或自动生成的字符串。

class Client(models.Model):
    link = models.CharField(max_length=254, default=link_generator())

我通过表单输入向/clients/端点发出POST请求 - 如果用户通过输入输入自定义字符串,它会按预期存储该字符串。如果他们将此字段留空,那很好 - 我想运行我的link_generator函数,它会创建一个随机字符串(下面的代码)。 相反,我得到一个错误 - Django REST Framework GUI告诉我,"这个字段可能不是空白。" 但是我没有指定它应该是必需的。如果我检查序列化器,它明确表示不需要它:

>>> from landing.serializers import ClientSerializer
>>> serializer = ClientSerializer()
>>> print(serializer)

ClientSerializer():
    id = IntegerField(label='ID', read_only=True)
    name = CharField(max_length=50, required=False)
    email = EmailField(max_length=254, required=False)
    notes = CharField(allow_blank=True, required=False, style={'type': 'textarea'})
    link = CharField(max_length=254, required=False)
    link_expired = BooleanField(required=False)
    created = DateTimeField(read_only=True)
    updated = DateTimeField(read_only=True)

更新:添加序列化程序代码w /建议改进 - 非常基本:

class ClientSerializer(serializers.ModelSerializer):

    class Meta:
        model = Client
        fields = ('id', 'name', 'email', 'notes', 'link', 'link_expired', 'created', 'updated')
        extra_kwargs = {
        'link': {
            'required': False,
         }
    }

Still, upon submitting I get this error every time.是什么让它认为需要字段?同样,我想允许用户将此字段留空,并运行link_generator函数(如果有)。如果我明确地说blank=True如下:

link = CharField(max_length=254, blank=True, default=link_generator())

... link_generator没有运行,最后存储空白字符串。对于它的价值,这里是我想在用户将输入留空的情况下运行的link_generator代码(旁注:我在模型上面声明了这个 - 这是不好的做法?应该在哪里宣布):

def link_generator(size=6, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))

有什么见解吗?我很难过 - 只是不明白为什么它应该被标记为这样。我总是对Django和REST相对较新 - 感谢任何帮助。

4 个答案:

答案 0 :(得分:1)

尝试将序列化程序更改为:

class ClientSerializer(serializers.ModelSerializer):

    class Meta:
        model = Client
        fields = ('id', 'name', 'email', 'notes', 'link', 'link_expired', 'created', 'updated')
        extra_kwargs = {
                'link': {
                    # Tell DRF that the link field is not required.
                    'required': False,
                    'allow_blank': True,
                 }
            }

我真的很惊讶当你打印序列化程序时,DRF说不需要link字段,因为根据你的模型,它应该是必需的(因为blank=True没有设置)。

编辑:allow_blank是用于CharField序列化程序字段的内容(如果设置为True,则应将空字符串视为有效值)。摘自此处的DRF文档:http://www.django-rest-framework.org/api-guide/fields/#charfield

答案 1 :(得分:1)

在@ user2719875的帮助下,我找到了解决方案。为了获得所需的行为 - 允许用户输入自定义字符串,如果没有给出输入,则默认为字符串生成器函数 - 我需要在序列化器本身而不是模型中定义默认值。使用extra_kwargs选择所需的链接'字段,我在这里声明默认函数:

class ClientSerializer(serializers.ModelSerializer):

class Meta:
    model = Client
    fields = ('id', 'name', 'email', 'notes', 'link', 'link_expired', 'created', 'updated')
    extra_kwargs = {
        'link': {
            'default': link_generator
         }
    }

有趣的是,它在models.py本身中查找link_generator函数,因此代码存储在模型上方。不确定这是否是最好的做法,但它确实有效。从模型中删除了default=link_generator,如下所示:

def link_generator(size=6, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))


class Client(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField(max_length=254)
    notes = models.TextField(blank=True)
    link = models.CharField(max_length=254)
    link_expired = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)  # added only on creation
    updated = models.DateTimeField(auto_now=True)  # updates each time the object is saved

工作得很好。谢谢你的帮助,全部!

答案 2 :(得分:0)

我在代码中看到的第一眼问题是默认选项。它应该是功能本身(没有括号)。把它改成这样的东西:

class Client(models.Model):
    link = models.CharField(max_length=254, default=link_generator)

希望它有所帮助!

答案 3 :(得分:0)

我的代码是

class AccountSerializer(serializers.ModelSerializer):

    users = serializers.CharField(write_only=True, required=False)
    name = serializers.CharField(write_only=True)
  

执行时:对于,用户='',需要序列化程序错误   领域。

     

必填= False&blank = True不起作用,

我还希望允许使用空白值。