将“ django-filter”与CHOICES字段一起使用-需要“ Any”选项 [英] Using 'django-filter' with CHOICES field - need "Any" option

查看:183
本文介绍了将“ django-filter”与CHOICES字段一起使用-需要“ Any”选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用非常酷的django-filter(通过: http://github.com/alex / django-filter
,或者似乎无法将我的头缠在文档上,或者只是
需要一点推动力。

I'm using the very cool django-filter (via: http://github.com/alex/django-filter) and either can't seem to wrap my head around the docs, or maybe just need a little boost.

当我在对象列表页面上显示过滤器表单时,对于FK字段,我
得到一个包含 -----的下拉列表,该结果导致
为 any类型过滤器。但是,我对该
模型的字段设置了一些选择,并且我想获得相同的 any类型选项。
这是来自models.py的相关示例部分:

When I show the filter form on an object list page, for a FK field I get the drop down that includes a "-----" which results in an "any" type filter. But I have some choices set to a field on that model, and I'd like to get the same "any" type option. Here's a relevant example portion from models.py:

TICKET_STATUS_CHOICES = (
    ('new', 'New'),
    ('accepted', 'Accepted'),
    ('assigned', 'Assigned'),
    ('reopened', 'Reopened'),
    ('closed', 'Closed'),
)

class Ticket(models.Model):
    assigned_to = models.ForeignKey(User, null=True, blank=True)
    status = models.CharField(max_length=20,
choices=TICKET_STATUS_CHOICES, default='new')

import django_filters

class TicketFilter(django_filters.FilterSet):
    class Meta:
        model = Ticket
        fields = ['assigned_to', 'status']

当我显示过滤器表单时,' assigned_to'得到一个'any'选项,因为
很好列出可用的用户。但是,状态 字段是
,仅限于实际 _CHOICES中列出的选项。

When I display the filter form, 'assigned_to' gets an 'any' option, as well as listing the available users. The 'status' field, however, is limited to only the options listed in the actual '_CHOICES'.

如何基于_CHOICES向字段添加任意选项?

How do I add an 'any' option to the fields based on _CHOICES?

推荐答案

如简短但实用的用法文档中所述,

As mentioned in the short but sweet 'usage' docs,

过滤器还接受任何传递到
django.forms.Field 构造函数中的任意关键字参数。

Filters also take any arbitrary keyword arguments which get passed onto the django.forms.Field constructor.

直到我再进一步看之前,这没有多大意义。在 ./ django-filter / docs / ref / 目录中,有 filters.txt 描述了过滤器字段和默认情况下,它们与哪些模型字段进行交互。 (我想我这里的语言正确,如果没有,请纠正我)。

This didn't make a lot of sense until I looked a bit further. In the ./django-filter/docs/ref/ directory, there's filters.txt which describes the Filter Fields and what Model Fields they interact with by default. (I think I've got the language right here, if not, correct me).

因此,我们可以看到 ChoiceFilter 用于任何带有选择项的字段。

So, we can see that ChoiceFilter is used for any field "with choices".

打起Django文档,这里重要的是表单域,以及表单域与模型的交互方式。 (使用Django表单)。因此,我们找到ChoiceField( http://docs.djangoproject.com/en / dev / ref / forms / fields /#choicefield )表示

Hitting up the Django documentation, what's important here is Form Fields, and how they interact with Models. (Using Django Forms). So we find ChoiceField (http://docs.djangoproject.com/en/dev/ref/forms/fields/#choicefield) which says


再加上一个必需的参数:
ChoiceField.choices
2个元组的可迭代(例如,列表或元组)用作此字段的选择。

Takes one extra required argument: ChoiceField.choices An iterable (e.g., a list or tuple) of 2-tuples to use as choices for this field.

因此您可以传递一个列表,而不仅仅是原始的Tuple选择集。

So you can pass it a list, not just the original Tuple choices set.

所以这可能不是pythonic或DRY,但是这是我更改相关模型的方法:

So this might not be pythonic or DRY, but here's how I changed the model in question:

class TicketFilter(django_filters.FilterSet):
    class Meta:
        model = Ticket
        fields = ['assigned_to', 'priority', 'status']

    def __init__(self, *args, **kwargs):
        super(TicketFilter, self).__init__(*args, **kwargs)
        self.filters['priority'].extra.update(
            {
                'choices': CHOICES_FOR_PRIORITY_FILTER
            })

此外,在上面定义了我的_CHOICES的地方,我定义了这个新的(上面提到的),并确保将原始选择附加到末尾:

And above that, where my _CHOICES were defined, I defined this new one (mentioned above) and made sure to append the original choices to the end:

CHOICES_FOR_PRIORITY_FILTER = [
    ('', 'Any'),
]
CHOICES_FOR_PRIORITY_FILTER.extend(list(TICKET_PRIORITY_CHOICES))

我在这里使用list()是因为原始的Choices是在tu中设置的ple,所以我想把它变成一个列表。另外,如果遇到NoneType错误,请确保不要尝试分配 .extend()的返回值,因为没有一个。我绊倒了,因为我忘记了它是 list 的方法,而不是返回新列表的函数。

I'm using list() here because the original Choices were set up in a tuple, so I want to turn that into a list. Also, if you're getting a NoneType error, be sure you're not attempting to assign the 'return value' of .extend(), because there isn't one. I tripped on this, because I forgot that it was a method of a list, and not a function that returned a new list.

如果您知道更简单,更干燥或 pythonic的方式,请告诉我!

If you know of an easier, more DRY or "pythonic" way to do this, please let me know!

这篇关于将“ django-filter”与CHOICES字段一起使用-需要“ Any”选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆