Django框架实现组合搜索 按照分类和标签显示文章

鳄鱼君

发表文章数:531

Vieu四代商业主题

高扩展、安全、稳定、响应式布局多功能模板。

¥69 现在购买
首页 » Python教程 » Django框架实现组合搜索 按照分类和标签显示文章

django实现组合搜索,就是网站中按照分类和标签显示文章。首先创建三张表,Article用于添加文章,Category文章分类,Tag文章标签:

from django.db import models

class Category(models.Model):
    cate=models.CharField(max_length=15)
class Tag(models.Model):
    article_tag=models.CharField(max_length=12)
class Article(models.Model):
    title=models.CharField(max_length=32)
    content=models.CharField(max_length=500)
    category=models.ForeignKey(Category,on_delete=models.CASCADE)
    article_tag=models.ForeignKey(Tag,on_delete=models.CASCADE)

接下来随意添加一点数据,然后配置URL路由规则,这里我就以index为列,进行说明,现在想让index.html页面把所有内容全部显示出来:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        a{display: inline-block;background-color: aqua;margin: 10px 10px; padding: 5px 5px;
        border: #FFFFFF solid 1px;cursor: pointer;}
    </style>
</head>
<body>
<strong>筛选条件</strong>
<div>
    <a>全部</a>
    {% for item in article_category %}
        <a>{{ item.article_cate }}</a>
    {% endfor %}
</div>
<div>
    <a>全部</a>
    {% for item in article_tag %}
        <a>{{ item.article_tag }}</a>
    {% endfor %}
</div>
<strong>查询结果</strong>
<dl>
    {% for item in result %}
    <dt>{{ item.id }}-{{ item.title }}</dt>
    {% endfor %}
</dl>

</body>
</html>
视图views中的index函数
def index(request):
    article_category = models.Category.objects.all()
    article_tag=models.Tag.objects.all()
    result=models.Article.objects.all()
    return render(request,
                  'index.html',
                  {'result':result,            
                'article_category':article_category,
                   'article_tag':article_tag})

如何实现分类和标签的筛选呢,就需要在URL上入手。URL传入两个参数一个为tag的id,另一个为category的id值,根据两个个数字来实现查询条件:

from django.urls import re_path
from myapp1 import views
urlpatterns = [
    re_path('^index-(?P<category_id>\d+)-(?P<article_tag_id>\d+).html/$', views.index,),

]

视图函数index
def index(request,*args,**kwargs):
    print(args,kwargs)#{'article_tag_id': '1', 'category_id': '1'}
    pid={}
    for k,v in kwargs.items():
        if v=='0': #如果id为0,则显示所有的选项
            pass
        else:
            pid[k]=v
    article_category = models.Category.objects.all()
    article_tag=models.Tag.objects.all()
    result=models.Article.objects.filter(**pid)
    return render(request,
                  'index.html',
                  {'result':result,
                'article_category':article_category,
                   'article_tag':article_tag})

这里我们URL规则接受两个id,一个为分类id,一个为标签id,通过id来实现手动的筛选,这里需要注意前一个为分类的id,后一个为标签的id,两者不要搞混。我们需要根据这两个参数来动态生成URL筛选:

视图函数
def index(request,*args,**kwargs):
  
    print(kwargs)
    pid={}
    for k,v in kwargs.items():
        kwargs[k]=int(v)
        if v=='0': #如果id为0,则显示所有的选项
            pass
        else:
            pid[k]=v
    article_category = models.Category.objects.all()
    article_tag=models.Tag.objects.all()
    result=models.Article.objects.filter(**pid)
    return render(request,
                  'index.html',
                  {'result':result,
                    'article_category':article_category,
                   'article_tag':article_tag,
                   'kwargs':kwargs
                   })
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        a{display: inline-block;background-color: aqua;margin: 10px 10px; padding: 5px 5px;
        border: #FFFFFF solid 1px;cursor: pointer;}
        a.active{background-color: brown}
    </style>
</head>
<body>
<strong>筛选条件</strong>
<div>
    {% if kwargs.category_id == 0 %}
        <a class="active" href="/index-0-{{ kwargs.article_tag_id }}.html/">全部分类</a>
    {% else %}
        <a  href="/index-0-{{ kwargs.article_tag_id }}.html/">全部分类</a>
    {% endif %}
    {% for item in article_category %} {# 循环输出分类 #}
        {% if item.id == kwargs.category_id %} {# item.id为分类的id,kwargs.category_id当前url中的标签的id #}
            <a class="active" href="/index-{{ item.id }}-{{ kwargs.article_tag_id }}.html/">{{ item.article_cate }}</a>
        {% else %}
            <a  href="/index-{{ item.id }}-{{ kwargs.article_tag_id }}.html/">{{ item.article_cate }}</a>
        {% endif %}
    {% endfor %}
</div>
<div>
    {% if kwargs.article_tag_id == 0 %}
        <a class="active" href="/index-{{ kwargs.category_id }}-0.html/">全部标签</a>
    {% else %}
        <a href="/index-{{ kwargs.category_id }}-0.html/">全部标签</a>
    {% endif %}
    {% for item in article_tag %}
        {% if item.id == kwargs.article_tag_id %}
            <a class="active" href="/index-{{ kwargs.category_id }}-{{ item.id }}.html/">{{ item.article_tag }}</a>
        {% else %}
            <a  href="/index-{{ kwargs.category_id }}-{{ item.id }}.html/">{{ item.article_tag }}</a>
        {% endif %}
    {% endfor %}
</div>
<strong>查询结果</strong>
<dl>
    {% for item in result %}
    <dt>{{ item.id }}-{{ item.title }}</dt>
    {% endfor %}
</dl>
</body>
</html>

每次筛选会记住当前的url,分类按照1-0、2-0、3-0、4-0以此类推,也就是说分类筛选只需要改变分类的id,我们在视图函数index中,传递的kwargs就包含了url参数信息,通过index-(?P\d+)-(?P\d+).html,切记参数不要搞混,在index模板中item.id为分类表中的id,所以前者需要使用item.id,后者用于筛选标签,标签通过url传递过来,就是kwargs.article_tag_id,两者结合可达到组合筛选,标签也是同理。

接下来是判断,因为我们要让当前选中的分类或者标签高亮显示。假设现在url为index-1-2.html,那么在分类筛选中,就应该判断当前的分类id,即kwargs.category_id 是否登录分类表中生成的id,两者相等高亮显示,标签同理,需要判断后一个参数。

对于全选高亮,假设现在url为index-0-5.html,我们只需要判断分类的id,也就是kwargs.category_id是否等于零,如果为零则url加上高亮属性并修改为/index-0-{{ kwargs.article_tag_id }}.html,这样就保证了第二个标签参数不受影响。反之同理,需要保证分类标签不受影响。换句话说,在分类筛选中全选要保证标签不受影响,在标签筛选中全选要保证分类不受影响。

可以看到我们的index.html模板中代码非常多,这里我们可以使用前面提到的自定义函数simple_tag,全部封装到一个函数里面,当然也没有减少代码,只是让index.html模板看起来更加简洁一点。

原理也是类同,我们需要把所有的判断全部放到函数里面,假设在myapp下templatetags中的fillter.py文件中:

from django import template
from django.utils.safestring import mark_safe
register=template.Library()

@register.simple_tag()
def filter_all(kwargs,filter_id):
    if filter_id=='category_id':
        n1=kwargs['category_id']
        n2=kwargs['article_tag_id']
        if n1==0:
            tem='<a class="active" href="/index-0-%s.html/">全部分类</a>' %n2
        else:
            tem='<a href="/index-0-%s.html/">全部分类</a>' % n2
    else: #filter_id=='article_tag_id'
        n1 = kwargs['category_id']
        n2 = kwargs['article_tag_id']
        if n2 == 0:
            tem = '<a class="active" href="/index-%s-0.html/">全部标签</a>' % n1
        else:
            tem = '<a href="/index-%s-0.html/">全部标签</a>' % n1
    return mark_safe(tem)

@register.simple_tag()
def filter_article(article,kwargs,k):
    ret=[]
    if k=='article_category':
        for item in article:
            if item.id==kwargs['category_id']:
                temp='<a class="active" href="/index-%s-%s.html/">%s</a>'% (item.id,kwargs['article_tag_id'],item.article_cate)
            else:
                temp = '<a  href="/index-%s-%s.html/">%s</a>' % (item.id, kwargs['article_tag_id'], item.article_cate)
            ret.append(temp)
    else:
        for item in article:
            if item.id == kwargs['article_tag_id']:
                temp = '<a class="active" href="/index-%s-%s.html/">%s</a>' % (kwargs['category_id'],item.id,  item.article_tag)
            else:
                temp = '<a  href="/index-%s-%s.html/">%s</a>' % (kwargs['category_id'],item.id,  item.article_tag)
            ret.append(temp)
    return mark_safe(''.join(ret))
{% load fillter %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        a{display: inline-block;background-color: aqua;margin: 10px 10px; padding: 5px 5px;
        border: #FFFFFF solid 1px;cursor: pointer;}
        a.active{background-color: brown}
    </style>
</head>
<body>
<strong>筛选条件</strong>
<div>
    {% filter_all kwargs 'category_id' %}
    {% filter_article article_category kwargs 'article_category' %}
</div>
<div>
    {% filter_all kwargs 'article_tag_id' %}
    {% filter_article article_tag kwargs 'article_tag'%}
</div>
<strong>查询结果</strong>
<dl>
    {% for item in result %}
    <dt>{{ item.id }}-{{ item.title }}</dt>
    {% endfor %}
</dl>
</body>
</html>

实现原理也是判断,通过index.html模板传入参数进行判断显示,这个不做过多介绍!

未经允许不得转载:作者:鳄鱼君, 转载或复制请以 超链接形式 并注明出处 鳄鱼君
原文地址:《Django框架实现组合搜索 按照分类和标签显示文章》 发布于2020-05-02

分享到:
赞(0) 赏杯咖啡

评论 抢沙发

6 + 7 =


文章对你有帮助可赏作者一杯咖啡

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.6主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册