我正在尝试使用ModelChoiceFilter来过滤基于作者的字母数据库。作者是一个外键,我似乎无法显示外键的“名称”值。
这是我所拥有的:
models.py(仅限相关位)
class Person(models.Model):
name = models.CharField(max_length=250, verbose_name='Full Name')
...
def __str__(self):
return self.name
class Letter(models.Model):
author = models.ForeignKey(Person, related_name='author', on_delete=models.PROTECT, verbose_name='Letter Author')
recipient = models.ForeignKey(Person, related_name='recipient', on_delete=models.PROTECT, verbose_name='Recipient')
...
title = models.CharField(max_length=250, verbose_name='Title of Letter')
def __str__(self):
return self.title
letter_filters.py
class LetterFilter(django_filters.FilterSet):
...
author = django_filters.ModelChoiceFilter(queryset=Letter.objects.order_by('author__name'))
class Meta:
model = Letter
fields = ['author', 'recipient']
我可以看到这种作品。这确实是对它的限制和正确排序,但是不是在选择框中显示作者姓名,而是在信件中显示“标题”(但我可以从标题中以正确的顺序看出来)。
我认为应该起作用的是这个
fields = ['author__name', 'recipient']
但这仍然继续列出Letter中的“标题”,而不是Person中的“名称”。
我知道它有我需要的,因为如果我这样做:
author = django_filters.ModelChoiceFilter(queryset=Letter.objects.order_by('author__name').values('author__name'))
我完全得到了我想要的!但是,它以{'author__name':'Jane Doe'}的形式出现,字段为author或author_name。我似乎无法获得正确的语法。
最后,我知道我可以做到:
author = django_filters.ModelChoiceFilter(queryset=Person.objects.order_by('name'))
返回正确排序的所有人员。但是,数据库中的人员不仅仅是作者。这与只允许使用默认字段['author'...,而不在类中设置author =(尽管无序)一样。
答案 0 :(得分:2)
您指定的查询集处理Letter
,因此,在这种情况下,Letter
被添加到ModelChoiceFiler
中,这根本不理想。
不过,您可以生成Person
的列表,这些列表至少写了一个字母,例如:
django_filters.ModelChoiceFilter(
queryset=Person.objects.filter(letter_set__isnull=False).order_by('name').distinct()
)
因此,这里我们过滤letter_set
不为空的事实,由于这将导致JOIN,其中Person
可能出现多次,因此我们向其中添加.distinct()
我发现这种建模非常奇怪(在您的三个示例中)。这基本上意味着您只能分配已经写入Person
的{{1}}。如果从未写过Letter
的人想写Letter
怎么办?
通常情况下,如果角色不同,则可以添加Letter
:
BooleanField
然后,我们可以过滤class Person(models.Model):
name = models.CharField(max_length=250, verbose_name='Full Name')
is_author = models.BooleanField(verbose_name='Is the person an author')
# ...
个Person
上的内容:
Author