'else' 子句中返回的对象的分页
Pagination for the objects returned in 'else' clause
我有以下模型,只有在我不按标签过滤时分页才能正常工作。一旦我按标签过滤广告,分页就不起作用了。
class AdListView(ListView):
paginate_by = 2
model = Ad
context_object_name = 'ads'
def get_context_data(self, **kwargs):
if self.request.GET.get('tags') is None:
context = super().get_context_data(**kwargs)
context.update(tags=Tag.objects.all())
return context
else:
tag_submitted = Tag.objects.get(name=self.request.GET.get('tags'))
ads_by_tag = tag_submitted.related_ads.all()
context = {
'ads': ads_by_tag
}
context.update(tags=Tag.objects.all())
return context
需要做些什么才能使分页适用于带过滤器和不带过滤器的两种情况?
下面是models.py和模板
models.py
class Tag(BaseModel):
def __str__(self):
return str(self.name)
class Ad(BaseModel):
name = models.CharField(max_length=100)
description = models.TextField(max_length=500)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
seller = models.ForeignKey(Seller, on_delete=models.CASCADE)
date_created = models.DateField(auto_now_add=True)
date_modified = models.DateField(auto_now=True)
tags = models.ManyToManyField(Tag, related_name='related_ads')
price = models.PositiveIntegerField(default=0)
archived = models.BooleanField(default=False)
def __str__(self):
return str(self.name)
class Meta:
ordering = ['-date_created']
模板
{% block content %}
<div class="container">
<div class="row">
<div class="w-75">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Title</th>
</tr>
</thead>
<tbody>
{% for ad in ads %}
<tr>
<td>{{ forloop.counter }}</td>
<td><a href="{% url 'ads-detail' ad.id %}"> {{ ad.name }} </a></td>
</tr>
{% empty %}
<li>No ads yet.</li>
{% endfor %}
</tbody>
</table>
</div>
<div class="w-25">
<table class="table">
<thead>
<tr>
<th scope="col">Tags</th>
</tr>
</thead>
<tbody>
{% for tag in tags %}
<tr>
<td><a href="{% url 'ads-list'%}?tags={{ tag }}"> {{ tag }} </a></td>
</tr>
{% empty %}
<li>No tags yet.</li>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
<a href="?page=1">« first</a>
<a href="?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">next</a>
<a href="?page={{ page_obj.paginator.num_pages }}">last »</a>
{% endif %}
</span>
</div>
</div>
</div>
{% endblock %}
所以这是一个学习django的项目,所以也欢迎任何其他关于如何改进代码的评论。
您应该不在.get_context_data()
[Django-doc]. In Django you pass the (possibly) filtered queryset in .get_queryset(…)
[Django-doc]中过滤。然后 Django 将对查询集进行分页,并将其添加到上下文中。通过覆盖上下文中的项目,您现在已经删除了分页查询集,并添加了一个过滤查询集。
因此您提供过滤后的查询集,让 Django 进行适当的分页:
class AdListView(ListView):
paginate_by = 2
model = Ad
context_object_name = 'ads'
def get_search_querystring(self):
copy = self.request.GET.copy()
copy.pop(self.page_kwarg, None)
return copy.urlencode()
def <strong>get_queryset</strong>(self, *args, **kwargs):
qs = super().get_queryset(*args, **kwargs)
if 'tags' in self.request.GET:
return qs.filter(tags__name=self.request.GET['tags'])
return qs
def get_context_data(*args, **kwargs):
return super().get_context_data(*args<strong>, tags=Tag.objects.all()</strong>, **kwargs)
另一个问题是模板中的 link:通过使用 ?page={{ page_obj.next_page_number }}
,这将“删除”包含搜索查询的 query string [wiki],并且只使用 page
作为查询字符串中的 only 变量。
因此在模板中我们可以使用 URL 作为:
<a href="?page={{ page_obj.next_page_number }}&{{ view.get_search_queryset|safe }}">
其他分页 links 也应该发生同样的情况。
我有以下模型,只有在我不按标签过滤时分页才能正常工作。一旦我按标签过滤广告,分页就不起作用了。
class AdListView(ListView):
paginate_by = 2
model = Ad
context_object_name = 'ads'
def get_context_data(self, **kwargs):
if self.request.GET.get('tags') is None:
context = super().get_context_data(**kwargs)
context.update(tags=Tag.objects.all())
return context
else:
tag_submitted = Tag.objects.get(name=self.request.GET.get('tags'))
ads_by_tag = tag_submitted.related_ads.all()
context = {
'ads': ads_by_tag
}
context.update(tags=Tag.objects.all())
return context
需要做些什么才能使分页适用于带过滤器和不带过滤器的两种情况?
下面是models.py和模板
models.py
class Tag(BaseModel):
def __str__(self):
return str(self.name)
class Ad(BaseModel):
name = models.CharField(max_length=100)
description = models.TextField(max_length=500)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
seller = models.ForeignKey(Seller, on_delete=models.CASCADE)
date_created = models.DateField(auto_now_add=True)
date_modified = models.DateField(auto_now=True)
tags = models.ManyToManyField(Tag, related_name='related_ads')
price = models.PositiveIntegerField(default=0)
archived = models.BooleanField(default=False)
def __str__(self):
return str(self.name)
class Meta:
ordering = ['-date_created']
模板
{% block content %}
<div class="container">
<div class="row">
<div class="w-75">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Title</th>
</tr>
</thead>
<tbody>
{% for ad in ads %}
<tr>
<td>{{ forloop.counter }}</td>
<td><a href="{% url 'ads-detail' ad.id %}"> {{ ad.name }} </a></td>
</tr>
{% empty %}
<li>No ads yet.</li>
{% endfor %}
</tbody>
</table>
</div>
<div class="w-25">
<table class="table">
<thead>
<tr>
<th scope="col">Tags</th>
</tr>
</thead>
<tbody>
{% for tag in tags %}
<tr>
<td><a href="{% url 'ads-list'%}?tags={{ tag }}"> {{ tag }} </a></td>
</tr>
{% empty %}
<li>No tags yet.</li>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
<a href="?page=1">« first</a>
<a href="?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">next</a>
<a href="?page={{ page_obj.paginator.num_pages }}">last »</a>
{% endif %}
</span>
</div>
</div>
</div>
{% endblock %}
所以这是一个学习django的项目,所以也欢迎任何其他关于如何改进代码的评论。
您应该不在.get_context_data()
[Django-doc]. In Django you pass the (possibly) filtered queryset in .get_queryset(…)
[Django-doc]中过滤。然后 Django 将对查询集进行分页,并将其添加到上下文中。通过覆盖上下文中的项目,您现在已经删除了分页查询集,并添加了一个过滤查询集。
因此您提供过滤后的查询集,让 Django 进行适当的分页:
class AdListView(ListView):
paginate_by = 2
model = Ad
context_object_name = 'ads'
def get_search_querystring(self):
copy = self.request.GET.copy()
copy.pop(self.page_kwarg, None)
return copy.urlencode()
def <strong>get_queryset</strong>(self, *args, **kwargs):
qs = super().get_queryset(*args, **kwargs)
if 'tags' in self.request.GET:
return qs.filter(tags__name=self.request.GET['tags'])
return qs
def get_context_data(*args, **kwargs):
return super().get_context_data(*args<strong>, tags=Tag.objects.all()</strong>, **kwargs)
另一个问题是模板中的 link:通过使用 ?page={{ page_obj.next_page_number }}
,这将“删除”包含搜索查询的 query string [wiki],并且只使用 page
作为查询字符串中的 only 变量。
因此在模板中我们可以使用 URL 作为:
<a href="?page={{ page_obj.next_page_number }}&{{ view.get_search_queryset|safe }}">
其他分页 links 也应该发生同样的情况。