Django中使用中间表过滤带标签博客文章的实现咨询
1 路由配置问题解答
你给出的路由规则需要添加到urls.py中,该规则可以将访问路径中tag/后的slug字符串作为参数传递给后续的视图函数,完全匹配按标签slug筛选文章的需求。
添加后示例urls.py代码参考:
from django.urls import path from . import views urlpatterns = [ # 原有其他路由 path('all-articles/', views.allarticles, name='allarticles'), path('tag/<str:tagslug>', views.tag, name='tag'), # 新增的标签筛选路由 ]
2 视图编写与ORM查询实现
你目前用中间表ArticleTags维护文章和标签的多对多关系,可以直接通过Django ORM的跨表双下划线语法实现筛选,视图代码参考如下:
from django.shortcuts import render, get_object_or_404 from django.core.paginator import Paginator from .models import Articles, Tags # 原有allarticles视图保持不变 def allarticles(request): articles_list = Articles.objects.all() paginator = Paginator(articles_list, 12) page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) context = {'page_obj': page_obj} return render(request, "All-articles.html", context) # 新增标签筛选视图 def tag(request, tagslug): # 先根据传入的slug获取对应的标签对象,不存在直接返回404 target_tag = get_object_or_404(Tags, tagslug=tagslug) # 跨中间表筛选关联的所有文章 articles_list = Articles.objects.filter(articletags__tag=target_tag) # 分页逻辑和原有保持一致,复用同一个模板渲染 paginator = Paginator(articles_list, 12) page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) # 可以额外把当前标签传到模板,用于展示当前筛选的标签名 context = {'page_obj': page_obj, 'current_tag': target_tag} return render(request, "All-articles.html", context)
如果希望简化ORM查询,可以在Articles模型中添加多对多字段指定关联中间表,后续可以直接通过tags字段查询:
# 修改models.py中的Articles模型 class Articles(models.Model): # 原有字段保持不变 title = models.CharField(max_length=155) metatitle = models.CharField(max_length=155) slug = models.SlugField(unique=True, max_length=155) summary = models.TextField(blank=True, null=True) field_created = models.DateTimeField(db_column='_created', blank=True, null=True) cover = models.ImageField(upload_to="cover", blank=True, default='logo-00-06.png') # 新增多对多关联,指定通过现有中间表关联 tags = models.ManyToManyField(Tags, through='ArticleTags', related_name='articles')
修改后上述视图中的筛选语句可以简化为:
articles_list = Articles.objects.filter(tags__tagslug=tagslug)
3 模板补充修改
你需要在现有All-articles.html中添加标签的点击入口,否则用户无法触发筛选请求,修改参考:
{% for article in page_obj %} <article> <div> <img src="/media/{{ article.cover }}" alt="menu item" class="article-photo" /> </div> <header> <h4>{{ article.title }}</h4> <!-- 新增标签展示区域 --> <div class="tag-list"> {% for assoc in article.articletags_set.all %} <a href="{% url 'tag' assoc.tag.tagslug %}">{{ assoc.tag.tag }}</a> {% endfor %} </div> </header> </article> {% endfor %}
内容的提问来源于stack exchange,提问作者haashe
相关产品推荐
相关产品推荐

