Django Filter Choice Field 显示正确的值但不会过滤
Django Filter Choice Field displays correct values but wont filter
我正在使用 Django 过滤器应用程序:https://github.com/carltongibson/django-filter
我正在制作一个网络漫画应用程序,我想要完成的是一个下拉筛选字段,它显示该字段的不同值。在这种情况下,series 字段。
阅读他们的文档后。以及 this one or 之类的堆栈溢出问题。我可以使过滤器表单显示正确的下拉值。但是当我尝试按它们进行过滤时,我的结果查询集 returns 没有值!
文档中一定有我不理解的地方。这是我的 hopefully 相关代码。
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 %}
结果:
我的过滤器表单为下拉项显示了正确、不同的 系列 。但是当我按任何值过滤时,查询集returns没有漫画
我也尝试在我的过滤器 class 中使用 ModelChoiceFilter 得到类似的结果(但值以元组格式显示):
series=django_filters.ModelChoiceFilter(queryset=ComicPanel.objects.all().values_list('series').distinct())
有人可以告诉我我做错了什么吗?
实际上我的错误很愚蠢,
如果我们看 Django docs for field.choices:
The first element in each tuple is the actual value to be set on the model, and the second element is the human-readable name.
所以这个方法:
# 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
returns 一个如下所示的列表:[(0,'series1'), (1, 'series2'), ...]
对于我的模型,元组的第一个值需要是系列名称。
所以列表应该是这样的:
[('series1','series1'), ('series2', 'series2'), ...]
所以简单的解决方法是更改此行:
series_list.append((i,item[0]))
对此:
series_list.append((item[0],item[0]))
我正在使用 Django 过滤器应用程序:https://github.com/carltongibson/django-filter
我正在制作一个网络漫画应用程序,我想要完成的是一个下拉筛选字段,它显示该字段的不同值。在这种情况下,series 字段。
阅读他们的文档后。以及 this one or
文档中一定有我不理解的地方。这是我的 hopefully 相关代码。
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 %}
结果:
我的过滤器表单为下拉项显示了正确、不同的 系列 。但是当我按任何值过滤时,查询集returns没有漫画
我也尝试在我的过滤器 class 中使用 ModelChoiceFilter 得到类似的结果(但值以元组格式显示):
series=django_filters.ModelChoiceFilter(queryset=ComicPanel.objects.all().values_list('series').distinct())
有人可以告诉我我做错了什么吗?
实际上我的错误很愚蠢,
如果我们看 Django docs for field.choices:
The first element in each tuple is the actual value to be set on the model, and the second element is the human-readable name.
所以这个方法:
# 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
returns 一个如下所示的列表:[(0,'series1'), (1, 'series2'), ...]
对于我的模型,元组的第一个值需要是系列名称。 所以列表应该是这样的: [('series1','series1'), ('series2', 'series2'), ...]
所以简单的解决方法是更改此行:
series_list.append((i,item[0]))
对此:
series_list.append((item[0],item[0]))