Django过滤器选择字段显示正确的值,但不会过滤

时间:2020-02-15 21:44:34

标签: python django python-3.6 django-filter

我正在使用Django过滤器应用程序:https://github.com/carltongibson/django-filter

我正在制作一个网络漫画应用程序,我想要完成的是一个下拉过滤器字段,该字段显示该字段的不同值。在这种情况下, 系列 字段。

阅读他们的文档后。并堆叠this onethis one之类的溢出问题。我可以使过滤器表单显示正确的下拉值。但是,当我尝试按它们过滤时,我的结果queryset不返回任何值!

文档中一定有我不了解的内容。这是我的希望相关代码。

models.py

class ComicPanel(models.Model):
    #... Other fields

    series = models.CharField(max_length = 255, null = False, blank = False, default = getMainSeriesName)

    # Other Filter Fields
    chapter = models.FloatField(null = True, blank = True)

    episode = models.IntegerField(null = True, blank = True)

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['series','chapter', 'episode'])
            ]

    def __str__(self):
        return self.title

    def save(self):  
        super(ComicPanel, self).save()  

filters.py

import django_filters
from .models import ComicPanel

# Grab Distinct values for series
def getUniqueSeries():
    series_dicts = ComicPanel.objects.all().values_list('series').distinct()
    series_list = []
    i = 0
    for item in series_dicts:
            series_list.append((i,item[0]))
            i = i+1
    return series_list

class ComicPanelFilter(django_filters.FilterSet):

    series = django_filters.ChoiceFilter(choices = getUniqueSeries())

    class Meta:
        model = ComicPanel
        fields = ['chapter', 'episode']

views.py

def view_archive(request):
    comic_list = ComicPanel.objects.all()
    comic_filter = ComicPanelFilter(request.GET, queryset=comic_list)
    paginator = Paginator(comic_filter.qs, 8)

    page = request.GET.get('page', 1)
    try:
        comics = paginator.page(page)
    except (PageNotAnInteger, TypeError):
        comics = paginator.page(1)
    except EmptyPage:
        comics = paginator.page(paginator.num_pages)

    return render(request, 'comics/comic_archive.html', context = {'filter': comic_filter, 'comics': comics})   

template.html

...

<form class="form" method="GET">
    {% csrf_token %}
    <table class="my_classes">
      <thead>
        <tr>
          <th scope="col">Filter Comics: </th>
          <th scope="col"></th>
        </tr>
      </thead>
          <tbody>
                {% for field in filter.form %}
                    <tr>
                        <th scope="row"> {{ field.name }}</th>
                        <td>{{ field }}</td>
                    </tr>
                {% endfor %}                          
          </tbody>
      </table>              
        <button type="submit" class="btn btn-outline-dark">Filter</button>       
</form> 

       ...

{% if comics %}
    {% for comic in comics %}                                   
            ...
    {% endfor %}

<!-- if no comics -->
{% else %}
        <p class = "my_class"> Looks like you don't have any comics! Upload some? </p>
{% endif %}

结果:

我的过滤器表单为下拉菜单项显示正确,独特的 系列 。但是当我过滤任何值时,查询集不会返回任何漫画

我还尝试在过滤器类中使用 ModelChoiceFilter ,结果类似(但值以Tuple格式显示):

series=django_filters.ModelChoiceFilter(queryset=ComicPanel.objects.all().values_list('series').distinct())

有人可以告诉我我在做什么错吗?

1 个答案:

答案 0 :(得分:0)

我的错误实际上很愚蠢,

如果我们看Django docs for field.choices:

每个元组中的第一个元素是要在模型上设置的实际值,第二个元素是人类可读的名称。

这种方法:

# Grab Distinct values for series
def getUniqueSeries():
     series_dicts = ComicPanel.objects.all().values_list('series').distinct()
     series_list = []
     i = 0
     for item in series_dicts:
            series_list.append((i,item[0]))
            i = i+1
     return series_list

返回一个看起来像这样的列表:[(0,'series1'),(1,'series2'),...]

对于我的模型,元组的第一个值必须是系列名称。 因此,列表应如下所示: [('series1','series1'),('series2','series2'),...]

因此,简单的解决方法是更改​​此行:

series_list.append((i,item[0]))

对此:

series_list.append((item[0],item[0]))