Всем привет!
Я работал над проблемой на работе и задавался вопросом, каков самый идиоматический способ ее решения. У нас есть несколько полей фильтра ModelMultipleChoiceFilter
для внешних ключей модели. Я пытаюсь понять, как выполнить фильтрацию по уникальному атрибуту внешних ключей при использовании виджета CheckboxSelectMultiple
, не раскрывая первичные ключи в URL-адресах.
Вот пример, который (более или менее) показывает, как я его настроил прямо сейчас.
# app/models.py
from django.db import models
class Foo(models.Model):
prop = models.CharField(max_length=55, unique=True)
def __str__(self):
return self.name
class Bar(models.Model):
foo = models.ForeignKey(Foo, related_name="bars")
# app/filters.py
import django_filters
from app.models import Bar, Foo
class BarFilter(django_filters.FilterSet):
foo = django_filters.ModelMultipleChoiceFilter(
queryset=Foo.objects.all(),
widget=CheckboxSelectMultiple(),
label="Foo",
label_suffix="",
)
class Meta:
model = bar
fields = ['foo']
Это прекрасно работает в представлении. Фильтры работают и фильтруют правильно с правильными виджетами. Однако в URL-адресе есть первичный ключ, поэтому в этом примере /?foo=1
, тогда как я хочу, чтобы он читал /?foo=<prop value>
, чтобы предотвратить раскрытие моего pk, а также сделать URL-адреса более читабельными.
Я пробовал изменять такие поля, потому что в другом месте в Django это работает:
# app/filters.py
...snip...
class Meta:
model = bar
fields = ['foo__prop']
Это заставляет URL-адрес отвечать на /?foo=<prop value>
по желанию, но теперь он не использует CheckboxSelectMultiple
для формы. Я также попытался превратить атрибут в foo__prop
, но рендеринг формы по-прежнему был некорректным.
У меня есть ощущение, что то, что я пытаюсь сделать, поддерживается, учитывая, что он почти работает, но я не могу понять, как это получить. Если это выходит за рамки текущей поддерживаемой области, я могу написать свою собственную форму, чтобы справиться с этим. Большое спасибо за любую помощь и за отличный проект!
Привет. Хорошая проблема. Строго говоря, вопрос использования, но так хорошо сформулирован, что читать одно удовольствие.
Вы смотрели на аргумент field_name для фильтров?
https://django-filter.readthedocs.io/en/master/ref/filters.html
Это позволит вам использовать foo_prop в качестве цели для вашего фильтра foo.
Я предполагаю, что это просто сработает ... может быть, вам нужно будет установить выбор в виджете или что-то в этом роде (но это нужно обработать ...)
Привет, спасибо, что нашли время ответить!
Ты поставил меня на правильный путь! Вчера у меня была возможность реализовать это, и использование аргумента field_name
сработало!
Для тех, кто в будущем может прочитать этот выпуск, вот пример того, как получился код:
# app/filters.py
...snip
class BarFilter(django_filters.FilterSet):
foo = django_filters.ModelMultipleChoiceFilter(
queryset=Foo.objects.all(),
field_name="foo__prop", # This lets us keep the url as "/?foo=<value>
to_field_name="prop",
widget=CheckboxSelectMultiple(),
label="Foo",
label_suffix="",
)
class Meta:
model = bar
fields = ['foo']
Вы можете найти ссылку на это в документации, упомянутой в ветке @carltongibson . В частности, см. Раздел о фильтрах ModelMultipleChoice.
В любом случае, большое спасибо за то, что нашли время, чтобы помочь мне!
Супер. Рад, что ты это решил. Отличная работа!
Отличная работа ! Спасибо !
Самый полезный комментарий
Привет, спасибо, что нашли время ответить!
Ты поставил меня на правильный путь! Вчера у меня была возможность реализовать это, и использование аргумента
field_name
сработало!Для тех, кто в будущем может прочитать этот выпуск, вот пример того, как получился код:
Вы можете найти ссылку на это в документации, упомянутой в ветке @carltongibson . В частности, см. Раздел о фильтрах ModelMultipleChoice.
В любом случае, большое спасибо за то, что нашли время, чтобы помочь мне!