我已经尝试了几个小时来让ModelMultipleChoiceFilter工作,并阅读了DRF和Django Filters文档。
我想能够根据通过ManyToManyField分配给它们的标签来过滤一组网站。例如,我希望能够获取已被标记为“烹饪”或“养蜂”的网站列表。
这是我的当前models.py中相关的代码片段:
class SiteTag(models.Model):
"""Site Categories"""
name = models.CharField(max_length=63)
def __str__(self):
return self.name
class Website(models.Model):
"""A website"""
domain = models.CharField(max_length=255, unique=True)
description = models.CharField(max_length=2047)
rating = models.IntegerField(default=1, choices=RATING_CHOICES)
tags = models.ManyToManyField(SiteTag)
added = models.DateTimeField(default=timezone.now())
updated = models.DateTimeField(default=timezone.now())
def __str__(self):
return self.domain
而我的当前views.py片段:
class WebsiteFilter(filters.FilterSet):
# With a simple CharFilter I can chain together a list of tags using &tag=foo&tag=bar - but only returns site for bar (sites for both foo and bar exist).
tag = django_filters.CharFilter(name='tags__name')
# THE PROBLEM:
tags = django_filters.ModelMultipleChoiceFilter(name='name', queryset=SiteTag.objects.all(), lookup_type="eq")
rating_min = django_filters.NumberFilter(name="rating", lookup_type="gte")
rating_max = django_filters.NumberFilter(name="rating", lookup_type="lte")
class Meta:
model = Website
fields = ('id', 'domain', 'rating', 'rating_min', 'rating_max', 'tag', 'tags')
class WebsiteViewSet(viewsets.ModelViewSet):
"""API endpoint for sites"""
queryset = Website.objects.all()
serializer_class = WebsiteSerializer
filter_class = WebsiteFilter
filter_backends = (filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter,)
search_fields = ('domain',)
ordering_fields = ('id', 'domain', 'rating',)
我刚刚测试了查询字符串[/path/to/sites]?tags=News
,我百分之百确定适当的记录存在,因为它们可以使用?tag
(缺少s
)查询正常工作(如描述的那样)。
我尝试过的其他内容示例:
tags = django_filters.ModelMultipleChoiceFilter(name='tags__name', queryset=Website.objects.all(), lookup_type="in")
我如何返回任何具有满足 name == A OR name == B OR name == C
的 SiteTag 的网站?
in
lookup_type
through the django-filter URL parser?的方法并创建自定义过滤器,暂时解决了我的问题。虽然如此,我仍然希望看到我的问题的解决方案,因为我相信它会对其他人有所帮助 - 而我不使用的代码也不会有错误 :) - Daniel Devine