Фильтр на поле с выбором - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть это поле:

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

С URL:

/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

EDIT

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 голосов
/ 06 ноября 2018

Выбранные вами варианты будут преобразованы в это питоническое представление:

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

Как видите, фактические значения, хранящиеся в вашем рабочем поле (в БД), равны '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)
0 голосов
/ 06 ноября 2018

Вы используете пакет django_filters , я рекомендую прочитать документы, так как у вас уже есть поддержка для этого

https://django -filter.readthedocs.io / о / мастер / исй / filters.html # choicefilter

Просто укажите choices значение, предложенное другими ответами (или посмотрите пример в документации)

0 голосов
/ 06 ноября 2018

Вы не определили пустой / стандартный выбор в OPERATIONS. Для этого добавьте что-то вроде этого:

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

Но вам также необходимо обновить модель:

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