3

我已经使用以下设置应用了 django-filters 的基本示例:models.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)

视图.py:

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

网址.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 %}

表格.py:

class ShopperForm(ModelForm):

    class Meta:
        model = Shopper

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

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

4

2 回答 2

6

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

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

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

现在,关于 django-filter。您所描述的是一个常见的要求,已经出现在django-filter 项目的问题中。请在此处查看可能的解决方法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 )
  元类:
    模型 = 模型。购物者
于 2013-08-23T06:26:03.103 回答
0

对于经验不足的人,这里是 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 没有错)
于 2016-10-11T03:48:32.623 回答