Django中组合搜索功能
需求分析
很多电商网站中有组合搜索的功能,所谓组合搜索就是网页中组合多个条件,对数据库中进行查询,并且将结果显示在页面中,看个例子吧:

注意红框中的标识,我们可以根据URL来做组合搜索.
video-3-1-1.html 使用split可以将三个数字取到,
第一位数字: 分类
第二位数字: 课程名称
第三位数字: 级别
分析到这里,我们就可以进行下一步了.
Code分析
urls.py
首先,如果想把url按我们的需求取出来,我们可以在urls.py中设置:
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
# url(r'^student/', views.student),
url(r'^video-(?P<direction_id>\d+)-(?P<classfication_id>\d+)-(?P<level_id>\d+).html', views.video),
]
说明下,这里是本身的正则表达式的语法,先分组,并且赋予了变量
1.此处的(?P<name>…),和普通的(?…):
基本类似。区别在于,此处由于是给此group命名了,所以,后续(同一正则表达式内和搜索后得到的Match对象中),都可以通过此group的名字而去引用此group。
2. group的名字,当前需要是正常的Python标识符,即字母,数字,下划线等,即,没有特殊的字符。
3.同一正则表达式内,每个group的组名,是唯一的,不能重复。
4. 虽然此处group内命名了,但是其仍然和普通的
这样,我们就可以在后续的代码中用到这些了!
modles.py
from django.db import models
# 技术方向,
class Direction(models.Model):
name = models.CharField(verbose_name='名称', max_length=32)
classification = models.ManyToManyField('Classification')
class Meta:
db_table = 'Direction'
verbose_name_plural = u'方向(视频方向)'
def __str__(self):
return self.name
# 技术分类、语言
class Classification(models.Model):
name = models.CharField(verbose_name='名称', max_length=32)
class Meta:
db_table = 'Classification'
verbose_name_plural = u'分类(视频分类)'
def __str__(self):
return self.name
# 技术视频,
class Video(models.Model):
level_choice = (
(1, u'初级'),
(2, u'中级'),
(3, u'高级'),
)
level = models.IntegerField(verbose_name='级别', choices=level_choice, default=1)
classification = models.ForeignKey('Classification', null=True, blank=True)
title = models.CharField(verbose_name='标题', max_length=32)
summary = models.CharField(verbose_name='简介', max_length=32)
img = models.ImageField(verbose_name='图片', upload_to='./static/images/Video/')
href = models.CharField(verbose_name='视频地址', max_length=256)
create_date = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'Video'
verbose_name_plural = u'视频'
def __str__(self):
return self.title
技术方向:多对多技术分类
技术视频:一对多技术分类
views.py
from django.shortcuts import render
from app01 import models
# Create your views here.
def video(request,**kwargs):
#在url.py中已经设置,结果为:{'direction_id': '3', 'classfication_id': '4', 'level_id': '1'}
print(kwargs)
print(request.path_info)
#request.path._info可以得到url的后缀,比如:/video-3-4-1.html
current_url = request.path_info
direction_id = kwargs.get('direction_id','0')
classfication_id = kwargs.get('classfication_id', '0')
q = {}
# 方向是0,表示是全部
if direction_id == '0':
#如果技术分类id为0,取分类数据库中的数据,为字典模式,元素为id和name
cList = models.Classification.objects.values('id', 'name')
# 分类是0
if classfication_id == '0':
# 如果课程也是全部,video-0-0
pass
else:
# video-0-1
# 否则,选中了对应的分类
q['classification__id'] = classfication_id
else:
#如果分类不是全部,得到分类对应的数据,通过map函数处理迭代器temp,并将其转化为列表,取得ID
obj = models.Direction.objects.get(id=direction_id)
temp = obj.classification.all().values('id','name')
id_list = list(map(lambda x:x['id'],temp))
cList = obj.classification.all().values('id','name')
if classfication_id == '0':
# video-1-0
# 根据方向ID,找到所属的分类ID
print(id_list)
q['classification__id__in'] = id_list
else:
# video-1-1
#如果分类ID在方向ID列表中
if int(classfication_id) in id_list:
q['classification__id'] = classfication_id
else:
q['classification__id__in'] = id_list
#url分割取分类的ID,然后改为0,修改url
url_list = current_url.split('-')
url_list[2] = "0"
current_url = '-'.join(url_list)
level_id = kwargs.get('level_id',None)
if level_id != '0':
q['level'] = level_id
result = models.Video.objects.filter(**q)
dList = models.Direction.objects.values('id', 'name')
lList = models.Video.level_choice
# level_choice = (
# (1, u'初级'),
# (2, u'中级'),
# (3, u'高级'),
# )
return render(request, 'video.html', {"dList":dList,
'cList': cList,
'lList': lList,
'current_url': current_url})
自定义扩展template函数
由于处理函数比较复杂,所以我们要写一些自定义的simple_tag函数,用来对相应的a标签进行href预处理,得到相应的url路径,xx.py:
from django import template
from django.utils.safestring import mark_safe
############################################
#此部分无用
register = template.Library()
@register.simple_tag
def action1(current_url, nid):
# /video-2-1-3.html
url_list = current_url.split('-')
url_list[1] = str(nid)
return '-'.join(url_list)
@register.simple_tag
def action2(current_url, nid):
# /video-2-1-3.html
url_list = current_url.split('-')
url_list[2] = str(nid)
return '-'.join(url_list)
@register.simple_tag
def action3(current_url, nid):
# /video-2-1-3.html
url_list = current_url.split('-')
url_list[3] = str(nid) + '.html'
return '-'.join(url_list)
###################################################
@register.simple_tag
def ac1(current_url, nid, name):
# # /video-2-1-3.html
url_list = current_url.split('-')
old = url_list[1]
if old == str(nid):
temp = '<a class="active" href="%s">%s</a>'
else:
temp = '<a href="%s">%s</a>'
url_list[1] = str(nid)
tag = temp %('-'.join(url_list),name)
return mark_safe(tag)
@register.simple_tag
def ac2(current_url, nid, name):
# # /video-2-1-3.html
url_list = current_url.split('-')
old = url_list[2]
if old == str(nid):
temp = '<a class="active" href="%s">%s</a>'
else:
temp = '<a href="%s">%s</a>'
url_list[2] = str(nid)
tag = temp %('-'.join(url_list),name)
return mark_safe(tag)
@register.simple_tag
def ac3(current_url, nid, name):
# # /video-2-1-3.html
url_list = current_url.split('-')
old = url_list[3]
if old == str(nid) + '.html':
temp = '<a class="active" href="%s">%s</a>'
else:
temp = '<a href="%s">%s</a>'
url_list[3] = str(nid) + '.html'
tag = temp %('-'.join(url_list),name)
return mark_safe(tag)
@register.simple_tag
def all_menu(current_url):
# video-0-10-0.html
url_list = current_url.split('-')
if url_list[1] == '0':
temp = '<a class="active" href="%s">全部</a>'
else:
temp = '<a href="%s">全部</a>'
url_list[1] = '0'
temp = temp %('-'.join(url_list))
return mark_safe(temp)
vedio.html
{% load xx %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
// 设定之间的间隔
.condition a{
display: inline-block;
padding: 5px;
}
// 设定当前选择条件的css样式
.condition a.active{
background-color: coral;
color: white;
}
</style>
</head>
<body>
<div class="condition">
<div>
// 处理全部
{% all_menu current_url %} :
// 遍历方向列表
{% for i in dList %}
// 将方向列表中的id,name作为参数传入定义好的自定义函数中处理,生成
{% ac1 current_url i.id i.name %}
{% endfor %}
</div>
<div>
{% for i in cList %}
{% ac2 current_url i.id i.name %}
{% endfor %}
</div>
<div>
{% for i in lList %}
{% ac3 current_url i.0 i.1 %}
{% endfor %}
</div>
</div>
</body>
</html>
页面中的搜索条件距离,可以使用css来控制
Django中组合搜索功能的更多相关文章
- Django之组合搜索组件(二)--另附simple_tag的创建使用方法
这次的代码为Django之组合搜索组件(一)的改版,实现的结果和(一)相同,不同的是,这次运用simple_tag方式,使.html程序简化 所以现在就开始编程吧! 首先想使用simple_tag方法 ...
- Django 之组合搜索
现在很多网站都会有这样的组合搜索功能,其实质是几个模型之间组合对数据库进行查询,并将结果显示到页面上. 每一行都是一个模型,模型之间有着连表关系(一对多.多对多等) 模型设计 总共四个模型:分别为方向 ...
- Django实现组合搜索的方法示例
目录 一.实现方法 二.基本原理 三.代码样例 方法1:纯模板语言实现 方法二:使用simpletag实现 四.其他变化 1.model定义 2.处理函数变化 3.simpletag相应改变 一. ...
- Django实现组合搜索
一.实现方法 1.纯模板语言实现 2.自定义simpletag实现(本质是简化了纯模板语言的判断) 二.基本原理 原理都是通过django路由系统,匹配url筛选条件,将筛选条件作为数据库查询结果,返 ...
- python(Django之组合搜索、JSONP、XSS过滤 )
一.组合搜索 二.jsonp 三.xss过滤 一.组合搜索 首先,我们在做一个门户网站的时候,前端肯定是要进行搜索的,但是如果搜索的类型比较多的话,怎么做才能一目了然的,这样就引出了组合搜索的这个案例 ...
- Django学习---组合搜索组件
组合搜索组件 我们都会写博客,写文章之后我们要给文章设置目录,设置类型.之后我们在浏览文章的时候就能够按类别进行精确定位到文章,那这个组合搜索我们应该怎么做呢? 首先我们先创建3张表,分别存放文章,文 ...
- Django之组合搜索组件(一)
什么是组合搜索呢? 比如你想买车,但手里只有10万块!所以你只能在10万块的车里挑选,但你喜欢黑色,因为觉得很高端大气上档次,说白了就是装逼杠杠的!之后售车姐给你拿了个表表,你看到了低于10万块且颜色 ...
- 【Python之路】特别篇--组合搜索功能实现
组合搜索: 根据特定标签内容,返回符合的数据. 效果图: 设计规划: 一.数据库表划分: 1.方向表,(运维自动化,Python开发,..) 2.分类表,(Python,Java,C#,.) 3.多对 ...
- Django中Q搜索的简单应用
本节涉及: 1.Q搜索在前后端的设计 2.Django中Queryset对象的序列化(由后端扔给前端的数据必然会经过序列化) 3.前端动态地构造表格以便显示(动态创建DOM对象) 思路: 用户通过前端 ...
随机推荐
- 计算 S=a+aa+aaa+aaaa+a.......a【转载】
package java算法; import java.util.Scanner; /* * 计算 S=a+aa+aaa+aaaa+a.......a */ public class numadd { ...
- PyCharm 注释
1.1 单行注释(行注释) 语法格式: #[空格]说明性文字信息 注:可放一行代码的后面进行说明 添加快捷键: Ctrl+/ 取消快捷键: 同上 1.2 多行注释(块注释) 语法格式: " ...
- ARM 平台下的 SSHD 配置
sshd_config 文件中 允许 root 用户登录 PermitRootLogin yes 配置为内部的 sftp Subsystem sftp internal-sftp key 配置 ssh ...
- android中的5大布局
1.线性布局:LinearLayout layout_margin 上下左右的距离分别为 下面图中的orientation表示的是布局中的方向 分别有horizontal表示水平 vertic ...
- BZOJ5340: [Ctsc2018]假面【概率+期望】【思维】
LINK 思路 首先考虑减血,直接一个dp做过去,这个部分分不难拿 然后是\(op=1\)的部分 首先因为要知道每个人被打的概率,所以需要算出这个人活着的时候有多少个人活着时概率是什么 那么用\(g_ ...
- HDU 2009
求数列的和 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submiss ...
- CTF之MD5
MD5是一种常见的加密方式,但准确来说,它只是一种编码方式,它将任意有限长度的字符串通过哈希函数转换为特定长度的字符串. MD5编码具有单向性,即由明文变密文简单,由密文变明文困难. 破解时只能通过暴 ...
- 好使-利用python 下paramiko模块无密码登录
[root@salt-minion02 paramiko]# vim baoleiji4.py # -*- coding:utf-8 -*-import paramikoprivate_key = p ...
- ory Oathkeeper docker-compose 安装运行
Oathkeeper 相关介绍可以参考官方文档,主要就是cloud native 身份以及访问代理 运行环境使用docker 安装(api proxy ) Dockerfile api: docker ...
- 二叉搜索树的第k大的节点
题目 给定一颗二叉搜索树,请找出其中的第k大的结点. 思路 如果中序遍历一棵二叉搜索树,遍历序列的数值则是递增排序,因此只需中序遍历一个二叉搜索树即可. #include <iostream&g ...