Simplelistfilter По Умолчанию
У меня есть логическое поле в моей модели, представляет ли кто-то отменил свое членство или нет. Я пытаюсь создать пользовательский SimpleListFilter, который позволяет фильтровать это поле.
однако я действительно хочу показать только тех, кто не отменен по умолчанию. Есть ли способ выбрать опцию " Нет " по умолчанию? Это мой фильтр до сих пор:
class CanceledFilter(SimpleListFilter):
title = 'Canceled'
# Parameter for the filter that will be used in the URL query.
parameter_name = 'canceled'
def lookups(self, request, model_admin):
return (
(True, 'Yes'),
(False, 'No'),
)
def queryset(self, request, queryset):
if self.value() is True or self.value() is None:
return queryset.filter(canceled=True)
if self.value() is False:
return queryset.filter(canceled=False)
изменить: Я должен был выразиться яснее. Я специально пытаюсь сделать это в Admin взаимодействие. Когда я добавляю вышеуказанный фильтр в качестве list_filter в admin. Я получаю фильтр на стороне страницы администратора с 3 вариантами: все, да и нет.
Я хотел бы, чтобы выбор" нет " или ни один из вариантов не был установлен по умолчанию. Вместо этого выбор " все " всегда устанавливается по умолчанию. Есть ли какой-то нет hacky способ установить выбор фильтра по умолчанию или что-то в этом роде.
Basiclly в Admin когда они просматривают членов, Я только хочу показать активный (не отмененный) по умолчанию. Если они нажимают "все" или "Да", затем я хочу показать отмененные.
обновление: Обратите внимание, что это то же самое, что и вопрос фильтр по умолчанию в Django admin, но я этот вопрос сейчас 6 лет. Принятый ответ отмечен как требующий Django 1.4. Я не уверен, что этот ответ по-прежнему будет работать с новыми версиями Django или по-прежнему является лучшим ответом.
учитывая возраст ответы на другой вопрос, я не уверен, как мы должны действовать. Я не думаю, что есть любой способ объединить их.
2 ответов
пришлось сделать то же самое и наткнулся на ваш вопрос. Вот как я исправил его в своем коде (адаптированном к вашему примеру):
class CanceledFilter(SimpleListFilter):
title = 'Canceled'
# Parameter for the filter that will be used in the URL query.
parameter_name = 'canceled'
def lookups(self, request, model_admin):
return (
(2, 'All'),
(1, 'Yes'),
(0, 'No'),
)
def queryset(self, request, queryset):
if self.value() is None:
self.used_parameters[self.parameter_name] = 0
else:
self.used_parameters[self.parameter_name] = int(self.value())
if self.value() == 2:
return queryset
return queryset.filter(cancelled=self.value())
требуется некоторое объяснение. Строка запроса является только частью URL-адреса, и именно то, что подразумевает имя: запрос строка. Ваши значения поступают как строки, а не как логические или целые числа. Поэтому, когда вы звоните self.value()
возвращает строка.
если вы изучите URL, который вы получаете при нажатии на Да / нет, если не использовать пользовательский фильтр списка, вы увидите, что он кодирует его как 1/0, а не True / False. Я последовал той же схеме.
для полноты и наших будущих читателей, я также добавил 2 для всех. Без проверки, я предполагаю, что это было None
раньше. Но!--3--> также используется, когда ничего не выбрано, по умолчанию все. Кроме того, в нашем случае он должен по умолчанию False
, поэтому мне пришлось выбрать другое значение. Если вам не нужна опция Все, просто удалите окончательный if-блок в queryset
метод, и первый Кортеж в lookups
метод.
С этим в стороне, как это работает? Фокус в том, чтобы понять, что self.value()
просто возвращает:
self.used_parameters.get(self.parameter_name, None)
который является либо строкой, либо None
в зависимости от того, находится ли ключ в словаре или нет. Итак, это центральная идея: мы удостоверяемся, что он содержит целые числа, а не строки, так что self.value()
может использоваться в вызове queryset.filter()
. Специальный режим для значения для всех, которое 2: в этом случае просто верните queryset
вместо отфильтрованного набора запросов. Другое специальное значение -None
, что означает, что нет ключа parameter_name
в словарь. В этом случае, мы создаем с значением 0, так что False
становится значением по умолчанию.
Примечание: ваша логика была неправильной там; вы хотите, чтобы не отменен по умолчанию, но вы лечите None
аналогично True
. Моя версия исправляет это.
ps: да, вы можете проверить 'True'
и 'False'
а не True
и False
в своем querystring
метод, но тогда вы заметите, что правильный выбор не будет выделен, потому что первые элементы в вашем кортеже не совпадают (вы сравниваете строки с логическими значениями). Я попытался сделать первые элементы в строках кортежей, но тогда мне пришлось бы сделать сравнение строк или eval
в матче 'True'
to True
, что является уродливым / небезопасным. Поэтому лучше придерживаться целых чисел, как в моем примере.
посмотрите раздел под названием "добавление дополнительных методов менеджера"в ссылке ниже:
http://www.djangobook.com/en/2.0/chapter10.html
Вы можете добавить дополнительные модели.Менеджер к вашей модели, чтобы только вернуть людей, которые не отменили свое членство. Грубая реализация дополнительных моделей.Менеджер будет выглядеть так:
class MemberManager(models.Manager):
def get_query_set(self):
return super(MemberManager, self).get_query_set().filter(membership=True)
class Customer(models.Model):
# fields in your model
membership = BooleanField() # here you can set to default=True or default=False for when they sign up inside the brackets
objects = models.Manager # default Manager
members = MemberManager() # Manager to filter for members only
в любое время вам нужно получить список вас текущих членов только, вы бы тогда просто звоните:
Customer.members.all()