根据选择过滤字段

时间:2018-11-06 14:27:58

标签: django django-rest-framework django-filter

我有这个字段:

operation = models.CharField(max_length=10, choices=OPERATIONS)

具有此过滤器的工作原理:

class OperationFilter(django_filters.Filter):

    def filter(self, qs, value):
        try:
            qs = qs.filter(operation=value.upper())
        except:
            pass
        return qs

带有网址:

/api/v1/operation/?operation=CREATE

但是使用默认过滤器(没有额外的OperationFilter)会失败:

{
    "operation": [
        "Select a valid choice. %(value)s is not one of the available choices."
    ]
}

为什么对选择失败的字段进行过滤?

对于其他非选择字段,默认过滤器可以正常工作:

/api/v1/operation/?recipient=recipient-19

编辑

OPERATIONS

from enum import Enum

def enum_as_choices(enum_class):
    """From an enum class, generate choices for a django field"""
    return ((entry, entry.value) for entry in enum_class)

class OperationType(Enum):
    CREATE = 'CREATE'
    STATUS = 'STATUS'
    EXPAND = 'EXPAND'
    DELETE = 'DELETE'

OPERATIONS = enum_as_choices(OperationType)

3 个答案:

答案 0 :(得分:1)

您编写的选择将转换为以下pythonic表示形式:

(
    ('OperationType.CREATE', 'CREATE'), 
    ('OperationType.STATUS', 'STATUS'), 
    ('OperationType.EXPAND', 'EXPAND'), 
    ('OperationType.DELETE', 'DELETE')
)

如您所见,存储在操作字段(在DB中)的实际值为'OperationType.CREATE',依此类推。 因此,您应该将选择更改为常规常数选择,或者使用'OperationType.CREATE'之类的东西进行筛选,这不是IMO的好选择。

您还可以像这样更改enum_as_choices方法:

def enum_as_choices(enum_class):
    """From an enum class, generate choices for a django field"""
    return ((entry.name, entry.value) for entry in enum_class)

答案 1 :(得分:1)

您正在使用django_filters软件包,我建议您阅读文档,因为您已经对此提供支持

https://django-filter.readthedocs.io/en/master/ref/filters.html#choicefilter

只需指出您的choices到其他答案建议的值即可(或查看文档中的示例)

答案 2 :(得分:0)

您尚未在OPERATIONS中定义空白/默认选项。为此,请添加以下内容:

OPERATIONS = (
    ('', 'NONE'),
    # the rest of your choices here...
)

但是您还需要将模型更新为:

operation = models.CharField(max_length=10, choices=OPERATIONS, default='NONE')