2015-11-12 34 views
1

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

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

我使POST请求到/clients/端点形式输入 - 如果用户输入经由输入自定义串时,它存储该字符串按预期方式。如果他们将此字段留空,那很好 - 我想运行我的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) 

UPDATE:添加串行代码瓦特/建议改进 - 非常基本的:

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一般都比较陌生 - 感谢任何帮助。

+0

你可以更新你的文章,并包括你serializer.py文件中的ClientSerializer()吗?我知道你打印出串行器,但以防万一...... – user2719875

+0

没问题,完成! – jckstl

回答

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 

伟大的工作。感谢您的帮助!

0

我可以在代码中看到的第一眼看到的问题是默认选项。它应该是函数本身(没有括号)。改变它是这样的:

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

希望它有帮助!

+0

这不是他错误的原因,但它确实是他的代码中的一个错误。 – spectras

+0

@spectras,我真的会推荐作者来测试它......我想我以前有这样的问题。 –

+0

谢谢,全部。我实际上已经尝试了两种方法,w /和w/o括号,但感谢您解释正确的方式......仍在努力! – jckstl

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

+0

呃......我试过这个,没有运气,结果一样。如果我将模型设置为'blank = True',则它每次都会存储一个空字符串,而不是存储link_generator函数的返回值。不知道发生了什么...还有其他想法吗? – jckstl

+0

@jckstl等等,你是否尝试了上面的代码而不设置'blank = True'?不要在你的模型上设置'blank = True',并尝试使你的序列化程序成为我上面的内容。在使用序列化程序时,上面提供了什么错误未在模型上设置“blank = True”? – user2719875

+0

尝试了两种方法,结果相同: '{ “链接”:[ “此字段可能不为空。” ] }' – jckstl

相关问题