我想使用带有标签的Django过滤器显示相关帖子。 我写了这个过滤器,但是Queryset不会过滤标题。 也许有人可以给我一个提示,说明如何重写我的过滤器以显示与同一标签相关的所有帖子。
我在app_tags.py中的过滤器
@register.filter(name='related_posts')
def related_posts(tag):
posts = Post.objects.filter(tags__name__in = [tag])
return posts.title()
我的HTML:
<div class="containernav">
<div class="mt-3 p-3 bg-white rounded box-shadow border border-gray">
<h6 class="border-bottom border-gray pb-2 mb-0">Verwandte Posts</h6>
<div class="media text-muted pt-3">
{% load app_tags %}
<a href="{% url 'post_detail' post.slug %}">{{ tag | related_posts }}</a>
</p>
</div>
</div>
</div>
我对posts.count进行了相同的操作,效果很好。但是,它不会显示所有带有相同标签的帖子的标题。 在上述情况下,它说Querset没有属性'title'。
我也尝试过这个:
app_tags.py
@register.filter(name='related_posts')
def related_posts(self):
return Post.objects.filter(tags__in=self.tags.all())
HTML:
<div class="mt-3 p-3 bg-white rounded box-shadow border border-gray">
<h6 class="border-bottom border-gray pb-2 mb-0">Verwandte Posts</h6>
<div class="media text-muted pt-3">
{% load app_tags %}
{% for post in posts.related_posts %}
<a href="{% url 'post_detail' post.slug %}">{{ post.title }}</a>
</p>
{% endfor %}
</div>
</div>
models.py
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
updated_on = models.DateTimeField(auto_now= True)
content = RichTextField(config_name='awesome_ckeditor')
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=1)
tags = TaggableManager()
我的app_tags.py
from blog.models import Post
from django import template
register = template.Library()
@register.filter(name='count_tags_usage')
def count_tags_usage(tag):
posts = Post.objects.filter(tags__name__in = [tag])
return posts.count()
@register.filter(name='related_posts')
def related_posts(tag):
posts = Post.objects.filter(tags__name__in = [tag])
# iterate over the QuerySet [posts]
for i in posts:
return i.title
我的新HTML配置:
<div class="containernav">
<div class="mt-3 p-3 bg-white rounded box-shadow border border-gray">
<h6 class="border-bottom border-gray pb-2 mb-0">Verwandte Posts</h6>
<div class="media text-muted pt-3">
{% for tag in post.tags.all %}
{% load app_tags %}
<a href="{% url 'post_detail' post.slug %}">{{ tag | related_posts }}</a>
{% endfor %}
</p>
</div>
</div>
</div>
我的views.py
from django.views import generic
from .models import Post
from django.shortcuts import render
from django.db.models import Q
from django.shortcuts import redirect
class PostList(generic.ListView):
model = Post
template_name = 'index.html'
paginate_by = 15
class PostDetail(generic.DetailView):
model = Post
template_name = 'post_detail.html'
def tag(request, slug):
posts = Post.objects.filter(tags__slug=slug)
return render(request, 'index.html', {"post_list": posts, "slug": tag})
def about(request):
return render(request, 'about.html', {})
##def verzeichnis(request):
##return render(request, 'verzeichnis.html', {})
def searchposts(request):
if request.method == 'GET':
query= request.GET.get('q')
submitbutton= request.GET.get('submit')
if len(query) == 0:
return redirect( 'https://www.code-reminder.com/')
if query is not None:
lookups= Q(title__icontains=query) | Q(content__icontains=query)
results= Post.objects.filter(lookups).distinct()
context={'results': results,
'submitbutton': submitbutton}
return render(request, 'search.html', context)
else:
return render(request, 'search.html')
else:
return render(request, 'search.html')
我的urls.py
from . import views
from django.urls import path
from django.urls import include
from django.views.generic.base import RedirectView
urlpatterns = [
path('', views.PostList.as_view(), name='home'),
path('about', views.about, name='about'),
##path('verzeichnis', views.verzeichnis, name='verzeichnis'),
path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'),
path("tag/<slug:slug>/", views.tag, name='tag'),
答案 0 :(得分:0)
“ QuerySet”对象没有属性“ title”
这是由于尝试执行[queryset].title
而导致的错误消息。
Django返回QuerySet作为对象列表。
因此,您可以这样做
def related_posts(tag):
posts = Post.objects.filter(tags__name__in = [tag]).distinct()
# iterate over the QuerySet [posts]
for i in posts:
return i.title
更新
根据我的观察,如果views.py
实际上在您希望完成此操作的地方渲染了实际的template
,那么您可能实际上并不需要模板过滤器,因为您已经完成了filtering
在view
说明
../tag/cars/
获得包含Posts
和tag
slug = car
的列表
在您的view
def tag(request, slug):
# returns posts with tags__slug = slug
posts = Post.objects.filter(tags__slug=slug)
return render(request, 'index.html', {"post_list": posts, "slug": tag})
然后您的template
变为
<div class="media text-muted pt-3">
{% for post in post_list %}
<a href="{% url 'post_detail' post.slug %}">{{ post.title }}</a>
{% endfor %}
PostDetail视图的更新
因此,我们现在可以暂时放弃自定义模板过滤器,并将过滤后的related_posts
作为上下文传递到PostDetail
PostDetail
视图变为
class PostDetail(generic.DetailView):
model = Post
template_name = 'post_detail.html'
def get_context_data(self, **kwargs):
context = super(PostDetail, self).get_context_data(**kwargs)
slug = self.kwargs['slug']
main_post = Post.objects.get(slug=slug)
# get all related_post and exclude the main post, makes sense that way
related_posts = Post.objects.filter(tags__name__in=list(main_post.tags.all())).distinct().exclude(slug=slug)
# add related_posts to the context
context['related_posts'] = related_posts
return context
然后将template
更新为
<div class="containernav">
<div class="mt-3 p-3 bg-white rounded box-shadow border border-gray">
<h6 class="border-bottom border-gray pb-2 mb-0">Verwandte Posts</h6>
<div class="media text-muted pt-3">
{% for posts in related_posts %}
<a href="{% url 'post_detail' posts.slug %}">{{ posts.title }}</a>
{% endfor %}
</div>
</div>
</div>