你好呀!
我正在处理工作中的一个问题,想知道解决它的最惯用的方法是什么。 我们有多个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']
这在视图中完全正常。 过滤器使用正确的小部件正常工作和过滤。 但是,网址中有主键,因此在此示例中/?foo=1
,而我希望它读取/?foo=<prop value>
,以防止暴露我的 pk 并使网址更具可读性。
我尝试修改这样的字段,因为在 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 过滤器部分。
无论如何,非常感谢您抽出时间来帮助我!