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
接下来是判断,因为我们要让当前选中的分类或者标签高亮显示。假设现在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模板传入参数进行判断显示,这个不做过多介绍!
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!