【问题标题】:How to display empty_label for non-mandatory fields with django-filter?如何使用 django-filter 显示非必填字段的 empty_label?
【发布时间】:2013-08-06 21:47:20
【问题描述】:

我已经使用以下设置应用了 django-filters 的基本示例: 模型.py

class Shopper(models.Model):
    FirstName = models.CharField(max_length=30)     
    LastName = models.CharField(max_length=30)      
    Gender_CHOICES = (
        ('','---------'),
        ('Male','Male'),
        ('Female','Female'),
    )
    Gender = models.CharField(max_length=6, choices=Gender_CHOICES, default=None)
        School_CHOICES = (
        ('','---------'),
        (u'1', 'Primary school'),
        (u'2', 'High School'),
        (u'3', 'Apprenticeship'),
        (u'4', 'BsC'),
        (u'5', 'MsC'),
        (u'6', 'MBA'),
        (u'7', 'PhD'),
    )
    HighestSchool = models.CharField(max_length=40, blank = True, choices = School_CHOICES,default=None)

views.py:

def shopperlist(request):
    f = ShopperFilter(request.GET, queryset=Shopper.objects.all())
    return render(request,'mysapp/emailcampaign.html', {'filter': f})

urls.py:

   url(r'^emailcampaign/$', views.shopperlist, name='EmailCampaign'),

模板:

{% extends "basewlogout.html" %}

{% block content %}
{% csrf_token %}
    <form action="" method="get">
    {{ filter.form.as_p }}
    <input type="submit" name="Filter" value="Filter" />
    </form>

        {% for obj in filter %}
            <li>{{ obj.FirstName }} {{ obj.LastName }} {{ obj.Email }}</li>
        {% endfor %}

       <a href="{% url 'UserLogin' %}"> 
       <p> Return to home page. </p> </a>
{% endblock %}

forms.py:

class ShopperForm(ModelForm):

    class Meta:
        model = Shopper

添加了空选项 ('','---------') 以确保 django-filters 将在过滤期间显示它并让该字段未指定。但是,对于非强制性的 HighestSchool 字段,当在带有 ModelForm. 的创建场景中使用模型时,它会显示两次,即('','---------') 不应列为非必填字段。那么在过滤时无法选择empty_label...

如何通过在创建视图期间列出一个 empty_label 来解决此问题,并有可能在过滤期间未指定必填字段和非必填字段?

【问题讨论】:

  • 您在HighestSchool 上有blank=True,因此您无需手动添加('','---------'),它将在稍后自动添加。这就是您看到双空标签的原因。
  • 没错,但是,如果我将其删除并转到过滤器,则没有空选项。但是,我确实希望在过滤中有空选项,并且不想指定某个学校选项。

标签: python django django-filters


【解决方案1】:

首先,您不应该将空白选项添加到您的选项集中。所以请删除以下行:

('','---------'),

当不需要该字段并且所有内容(django 模型、django 表单、django 视图等)除了django-filter 将按预期工作时,Django 会自动添加这些。

现在,关于 django-filter。您所描述的是一个常见的要求,已经出现在django-filter project 的问题中。请在此处查看可能的解决方法https://github.com/alex/django-filter/issues/45。我将从那里复制粘贴 cvk77 的代码以供参考:

类 NicerFilterSet(django_filters.FilterSet): def __init__(self, *args, **kwargs): super(NicerFilterSet, self).__init__(*args, **kwargs) 对于名称,self.filters.iteritems() 中的字段: 如果是实例(字段,ChoiceFilter): # 将“任何”条目添加到选择字段。 field.extra['choices'] = tuple([("", "Any"), ] + list(field.extra['choices']))`

所以要使用它,只需从 NicerFilterSet 扩展您的过滤器,而不是普通的 FilterSet。

您还可以执行以下 Q+D 解决方案:在您的 models.py 中定义一个全局变量:

GENDER_CHOICES = ( ('男','男'), ('女','女'), )

并在您的模型中按预期使用它。

现在,在您的 filters.py 中定义另一个像这样的全局变量:

FILTER_GENDER_CHOICES = 列表(models.FILTER_CHOICES) FILTER_GENDER_CHOICES.insert(0, ('','---------') )

然后像这样定义你的过滤器:

类 ShopperFilter(django_filters.FilterSet): 性别 = django_filters.ChoiceFilter(choices= FILTER_GENDER_CHOICES ) 元类: 模型 = 模型。购物者

【讨论】:

  • 谢谢,这解决了问题!
  • 谢谢!我在下面发布了另一个适用于 Python 3 的答案,以防有人在运行 cvk777 答案时遇到问题。
【解决方案2】:

对于经验不足的人,这里是 cvk77 原始解决方法的 Python3 兼容版本,我在@Serafeim 接受的答案中找到了它。

class NicerFilterSet(django_filters.FilterSet):

def __init__(self, *args, **kwargs):
  super(NicerFilterSet, self).__init__(*args, **kwargs)

  for name, field in self.filters.items():
    if isinstance(field, ChoiceFilter):
      # Add "Any" entry to choice fields.
      field.extra['choices'] = tuple([("", "Any"), ] + list(field.extra['choices']))

变化:

  • self.filters.iteritems() 更改为 self.filters.items()
  • 删除错误的反引号(它也出现在 github 线程中 - @Serafeim 没有错)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-18
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 2019-07-11
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    相关资源
    最近更新 更多