选择字段中的 Django 空标签 - 没有查询集

Posted

技术标签:

【中文标题】选择字段中的 Django 空标签 - 没有查询集【英文标题】:Django empty label in choice field - no queryset 【发布时间】:2016-09-10 11:00:17 【问题描述】:

在选择字段上设置空标签给我带来了一些问题。我看过this 之类的答案,但这只是在谈论表单。

假设我有以下模型:

class MyColorModel(models.Model):
    BLUE = 'blue'
    RED = 'red'
    GREEN = 'green'
    COLOR_CHOICES = (
        (BLUE, 'Blue'),
        (RED, 'Red'),
        (GREEN, 'Green'))

   my_color = models.CharField(max_length=5, choices=COLOR_CHOICES, blank=True)

还有这个表格:

class MyColorForm(forms.ModelForm):
   class Meta:
       model = MyColorModel
       fields = ['mycolor']

默认情况下,这将显示一个选择字段,空白标签设置为 ------

我想出了以下选项来设置标签。

1) 将我的模型中的 COLOR_CHOICES 更改为:

COLOR_CHOICES = (
    ('', '---Please select your color---'),
    (BLUE, 'Blue'),
    (RED, 'Red'),
    (GREEN, 'Green'),

2) 将我的 model 中的 COLOR_CHOICES 更改为:

COLOR_CHOICES = (
    (None, '---Please select your color---'),
    (BLUE, 'Blue'),
    (RED, 'Red'),
    (GREEN, 'Green'),

3) 将以下 init 方法添加到我的模型 form 中:

def __init__(*args, **kwargs):
    super(MyColorForm, self).__init__(*args, **kwargs)
    self.fields['my_color'].choices =  [('', '---Please select your color---')] + MyColorModel.COLOR_CHOICES

选项 1 导致了一些副作用,即我开始失败的 if 语句,这就是导致我创建选项 2 的原因。

在我的模型中添加空白标签是否可以(选项 2)?如果我在那里添加它会有任何副作用,还是在表单上添加它更好?当我在表单中设置空标签时,似乎有很多代码。

【问题讨论】:

【参考方案1】:

所以您想为从您创建的所有模型表单设置empty_label?在选项中添加一个空选项很好,它甚至在docs 中说明。

除非在该字段上设置了 blank=False 以及默认值,否则 包含“---------”的标签将与选择框一起呈现。到 覆盖此行为,向包含 None 的选项添加一个元组;例如 (无,“您的显示字符串”)。或者,您可以使用空的 字符串而不是 None 在这有意义的地方 - 例如在 字符字段。

但为了停止显示默认值,您需要设置blank=False。所以尝试一下这样的事情:

class MyColorModel(models.Model):
    BLUE = 'blue'
    RED = 'red'
    GREEN = 'green'
    COLOR_CHOICES = (
        ('', '---Please select your color---')
        (BLUE, 'Blue'),
        (RED, 'Red'),
        (GREEN, 'Green'))

   my_color = models.CharField(max_length=5, choices=COLOR_CHOICES, blank=False, null=False, default='')

但在我看来,最好的方法就是在form.field 上设置empty_label

def __init__(*args, **kwargs):
    super(MyColorForm, self).__init__(*args, **kwargs)
    self.fields['my_color'].empty_label = '---Please select your color---'

【讨论】:

感谢您的回答。实际上,我也更喜欢将空标签设置为最后一个选项,但似乎这仅在模型字段是 ForeignKey 字段(即 modelchoicefield)时才有效。对我来说,在普通选择字段上设置空标签没有效果(使用 Django 1.9) 我在文档中读到了这个,所以我选择了选项 1:除非在字段上设置了 blank=False 以及默认值,然后一个标签包含“-------- -" 将与选择框一起呈现。要覆盖此行为,请向包含 None 的选项添加一个元组;例如(无,“您的显示字符串”)。或者,您可以在有意义的情况下使用空字符串而不是 None - 例如在 CharField 上。【参考方案2】:

在表单上设置您想要的内容是实现您想要的更正确的方法。在 Django 中,模型包含您存储的数据的基本字段和行为。也就是说,它们定义了您的信息在数据库中的结构。

1.我没有检查它,但是你的第一个选项
COLOR_CHOICES = (
    ('', '---Please select your color---'),
    (BLUE, 'Blue'),
    (RED, 'Red'),
    (GREEN, 'Green'),

my_color = models.CharField(max_length=5, choices=COLOR_CHOICES)

可能不起作用,因为您的首选是空字符串,但您的 my_color 字段不包含 blank=True 参数。这意味着它不允许将空字符串保存到数据库中。但是,如果您希望此字段是强制性的,那么您对空选项的定义不应该在这里,因为它不会带来任何附加值,因为它不包含有关您的数据结构的任何附加信息。

2.你的第二个选择绝对不是要走的路[1]:

避免在基于字符串的字段(例如 CharField 和 TextField)上使用 null,因为空字符串值将始终存储为空字符串,而不是 NULL。如果基于字符串的字段具有 null=True,这意味着它有两个可能的“无数据”值:NULL 和空字符串。在大多数情况下,“无数据”有两个可能的值是多余的; Django 的约定是使用空字符串,而不是 NULL。

3. 你的第三个选项看起来不错。我已经有一段时间没有使用 django 表单了,但是如果您的代码有效,那么表单是一个比在模型中更适合定义表单外观的地方,因此请选择该选项。

或者查看您帖子中链接的 SO 问题中的解决方案并实施这些解决方案。

祝你好运!

【讨论】:

谢谢!你是对的,对于选项 1,我需要其中的空白 = True。我打算选择选项 2,但我现在肯定会使用其他选项之一

以上是关于选择字段中的 Django 空标签 - 没有查询集的主要内容,如果未能解决你的问题,请参考以下文章

在 django 中查询多对多字段会产生一个空查询集

使用 ORM Django 过滤新更新的查询集返回空查询集

Django Newbie - 使用多字段表单,如何消除查询集中的空字段

检查 django 中的空查询集

在 Django 中,正确地制作具有多个类别、多个标签和搜索的查询集?

空查询返回数据库中的所有字段。Django