Django中组合搜索功能

需求分析

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

注意红框中的标识,我们可以根据URL来做组合搜索.

video-3-1-1.html 使用split可以将三个数字取到,
第一位数字: 分类
第二位数字: 课程名称
第三位数字: 级别

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),
]

URL

说明下,这里是本身的正则表达式的语法,先分组,并且赋予了变量

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

models

技术方向:多对多技术分类

技术视频:一对多技术分类

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','')
classfication_id = kwargs.get('classfication_id', '')
q = {}
# 方向是0,表示是全部
if direction_id == '':
#如果技术分类id为0,取分类数据库中的数据,为字典模式,元素为id和name
cList = models.Classification.objects.values('id', 'name')
# 分类是0
if classfication_id == '':
# 如果课程也是全部,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 == '':
# 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] = ""
current_url = '-'.join(url_list)
level_id = kwargs.get('level_id',None)
if level_id != '':
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})

view

自定义扩展template函数

由于处理函数比较复杂,所以我们要写一些自定义的simple_tag函数,用来对相应的a标签进行href预处理,得到相应的url路径,vied_tag.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] == '':
temp = '<a class="active" href="%s">全部</a>'
else:
temp = '<a href="%s">全部</a>' url_list[1] = ''
temp = temp %('-'.join(url_list)) return mark_safe(temp)

template

vedio.html

{% load vied_tag%}
<!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>

django实现图片瀑布流布局

我们在一些图片网站上经常会看到,满屏都是图片,而且图片都大小不一,却可以按空间排列。默认一个div是占用一行,当想把div里的图片并排显示的时候,只能使用float属性,但是,如果两张图片大小不一,那么第二行图片会以第一张最大的图片占用的空间为基准,进行第二行显示,这样的图片布局就非常难看,今天实现的就是瀑布流的形式

实现效果:

一般我们做图片布局的时候,都是采用div中加入img,然后将div float起来,这样图片就会并排显示。实现瀑布流的原理就是,我们换一种布局方式,首先定义好需要显示多少列图片,多少列就是多少和div,然后在每列的div中去加入div包着的图片,由于图片外的div是行标签,所以默认独占一行,所以,在本列的div中,图片就无缝的向下排列了,同理,其他列也是,这样总体布局就出现了,看下图

view.py

def student(request):
img_list = [
{'src': '1.jpg', 'title': 'asdfasdfasdf','content': 'asdf'},#
{'src': '2.jpg', 'title': 'asdfasdfasdf','content': 'asdf'},#
{'src': '3.jpg', 'title': 'asdfasdfasdf','content': 'asdf'},
{'src': '4.jpg', 'title': 'asdfasdfasdf','content': 'asdf'},
{'src': '5.jpg', 'title': 'asdfasdfasdf','content': 'asdf'},#
{'src': '6.jpg', 'title': 'asdfasdfasdf','content': 'asdf'},
] return render(request, 'student.html', {"img_list":img_list})

首先分析,现在以四列布局 div分别是a、b、c、d, 那么图片1就在div a中,图片2就在div b中,图片3就在div c中,图片4就在div d中,到图片5时,就继续从div a中开始,后面依次。发现,其中的规律就是第多少张图片 n 除以 4,的余数m 就是第m个div。根据这个规律,我们可以使用模版语言中自定义的方法去进行判断,如果本图片 除以4,正好等于所比较的div 号,那么就放进去

代码:

templatetags-vied_tag

from django import template
register = template.Library() @register.filter
def detail1(value,arg): """
查看余数是否等于remainder arg="1,2"
:param counter:
:param allcount:
:param remainder:
:return:
"""
allcount, remainder = arg.split(',')
allcount = int(allcount)
remainder = int(remainder)
if value%allcount == remainder:
return True
return False

html 代码

{% load  vied_tag %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
.container{
width: 980px;
margin: 0 auto;
}
.container .column{
float: left;
width: 245px;
}
.container .item img{
width: 245px;
}
</style>
</head>
<body> <div class="container">
<div class="column">
{% for i in img_list %}
{% if forloop.counter|detail1:"4,1" %}
<div class="item">
{{ forloop.counter }}
<img src="/static/{{ i.src }}">
</div>
{% endif %}
{% endfor %}
</div>
<div class="column">
{% for i in img_list %}
{% if forloop.counter|detail1:"4,2" %}
<div class="item">
{{ forloop.counter }}
<img src="/static/{{ i.src }}">
</div>
{% endif %}
{% endfor %}
</div>
<div class="column">
{% for i in img_list %}
{% if forloop.counter|detail1:"4,3" %}
<div class="item">
{{ forloop.counter }}
<img src="/static/{{ i.src }}">
</div>
{% endif %}
{% endfor %}
</div>
<div class="column">
{% for i in img_list %}
{% if forloop.counter|detail1:"4,0" %}
<div class="item">
{{ forloop.counter }}
<img src="/static/{{ i.src }}">
</div>
{% endif %}
{% endfor %}
</div>
</div> </body>
</html>

上面只是简单的利用模版语言 实现了瀑布流布局,但是会发现图片列表需要循环四次,这样效率不好,一般情况下,可以使用ajax,先获取到图片列表,然后js去循环列表,然后在循环中,将当前循环的元素索引 去和4相除,拿到余数,最后使用jquery 根据余数进行直接定位到对应的

参考学习:https://www.cnblogs.com/pycode/articles/django3.html

												

Django实现瀑布流,组合搜索的更多相关文章

  1. 轮播组件/瀑布流/组合搜索/KindEditor插件

    一.企业官网 ### 瀑布流 ​ Models.Student.objects.all() #获取所有学员信息 ​ 通过div进行循环图片和字幕 ​ 1.以template模板方法实现瀑布流以列为单位 ...

  2. Django 之瀑布流实现

    需求分析 现在是 "图片为王"的时代,在浏览一些网站时,经常会看到类似于这种满屏都是图片.图片大小不一,却按空间排列,就这是瀑布流布局. 以瀑布流形式布局,从数据库中取出图片 每次 ...

  3. django实现瀑布流、组合搜索、阶梯评论、验证码

    django实现图片瀑布流布局 我们在一些图片网站上经常会看到,满屏都是图片,而且图片都大小不一,却可以按空间排列.默认一个div是占用一行,当想把div里的图片并排显示的时候,只能使用float属性 ...

  4. Django之瀑布流

    一. 小功能瀑布流的实现 1.完成效果图 2.代码部分 <1>models.py from django.db import models # Create your models her ...

  5. Django模板语言之组合搜索

    url.py from django.conf.urls import url from django.contrib import admin from app01 import views url ...

  6. python运维开发(二十二)---JSONP、瀑布流、组合搜索、多级评论、tornado框架简介

    内容目录: JSONP应用 瀑布流布局 组合搜索 多级评论 tornado框架简介 JSONP应用 由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. ...

  7. Django 之组合搜索

    现在很多网站都会有这样的组合搜索功能,其实质是几个模型之间组合对数据库进行查询,并将结果显示到页面上. 每一行都是一个模型,模型之间有着连表关系(一对多.多对多等) 模型设计 总共四个模型:分别为方向 ...

  8. Django 项目补充知识(JSONP,前端瀑布流布局,组合搜索,多级评论)

    一.JSONP 1浏览器同源策略 通过Ajax,如果在当前域名去访问其他域名时,浏览器会出现同源策略,从而阻止请求的返回 由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一 ...

  9. jsonp、瀑布流布局、组合搜索、多级评论(评论树)、Tornado初识

    1.JSONP原理剖析以及实现 1.1 同源策略限制 用django分别建立两个项目,jsonp01和jsonp02,然后再在这两个项目里分别建立一个app,比如名字叫jsonp1.jsonp2:js ...

随机推荐

  1. React 中的 Component、PureComponent、无状态组件 之间的比较

    React 中的 Component.PureComponent.无状态组件之间的比较 table th:first-of-type { width: 150px; } 组件类型 说明 React.c ...

  2. Scrapy 爬取BOSS直聘关于Python招聘岗位

    年前的时候想看下招聘Python的岗位有多少,当时考虑目前比较流行的招聘网站就属于boss直聘,所以使用Scrapy来爬取下boss直聘的Python岗位. 1.首先我们创建一个Scrapy 工程 s ...

  3. PyCharm 连接Git及使用

    一.PyCharm配置Git的环境 1.PyCharm 连接Git首先需要本机安装Git软件; 2.PyCharm 版本控制中设置Git的执行路径,file->Setting->Versi ...

  4. 删除JavaScript对象中的元素

    参考http://stackoverflow.com/questions/208105/how-to-remove-a-property-from-a-javascript-object 通过dojo ...

  5. DeviceIoControl 驱动交互

    驱动程序通信的函数,除了ReadFile和WriteFile函数还有DeviceIoControl函数,而且DeviceIoControl函数那是相当的彪悍.因为它可以自定义控制码,你只要在IRP_M ...

  6. java实现文件的上传和下载

    1. servlet 如何实现文件的上传和下载? 1.1上传文件 参考自:http://blog.csdn.net/hzc543806053/article/details/7524491 通过前台选 ...

  7. 网易云课堂js学习笔记

    javascript:用来在页面中编写特效的,和html/css一样都是由浏览器解析的 javascript语言: 一.js如何运行的(javaScript,jscript,vbscript,appl ...

  8. CentOS6.5_64位系统下安装配置postfix邮件系统 启用并配置SMTP虚拟账户

    http://blog.jjonline.cn/linux/185.html http://www.cnblogs.com/apexchu/p/4271264.html 用户新增和删除 http:// ...

  9. golang中defer的详解 转自https://blog.csdn.net/skh2015java/article/details/77081250

    Go里的defer很有用,尤其在很多执行模块化操作时,初始化时给各个需要执行的模块传入参数,但是这些参数有些事在模块执行过程中才赋值的. 这时候有了defer就不会把代码写的很凌乱. Go的defer ...

  10. OpenTSDB(时序数据库官网)

    官网地址:http://opentsdb.net/ 下载地址:https://github.com/OpenTSDB/opentsdb/releases ----------------------- ...