一、瀑布流,是指页面布局中,在显示很多图片时,图片及文字大小不相同,导致页面排版不美观

如上图,右边的布局,因为第一行第一张图片过长,第二行的第一张被挤到第二列了。示例:

def flow(request):user_list = [{'name': '张1三', 'src': '/static/image/1.jpg', 'company': '特事特办中国特色一公司','summary': '一群老油条烦死打法撒飞洒的飞洒烦死哒防守打法噶三群老油条烦死哒范德萨分散发士大夫士大夫是打发发防守打法烦死哒防守打法噶第三方三'},{'name': '张2三', 'src': '/static/image/1.jpg', 'company': '特事特办中国特色一公司','summary': '一群老油'},{'name': '张3三', 'src': '/static/image/1.jpg', 'company': '特事特办中国特色一公司','summary': '一群老油条烦分打发发防守打法撒飞洒的飞洒烦死哒防守打法噶第三'},{'name': '张4三', 'src': '/static/image/1.jpg', 'company': '特事特办中国特色一公司','summary': '一群老油条烦死哒范德萨分散发士大夫士大夫是打发发防守打法烦死哒防守打法噶第三方三'},{'name': '张5三', 'src': '/static/image/1.jpg', 'company': '特事特办中国特色一公司','summary': '一群老油条烦死哒范德萨分散发士大夫士大夫是打发发防守打法'},{'name': '张6三', 'src': '/static/image/1.jpg', 'company': '特事特办中国特色一公司','summary': '一群老油条烦死哒范洒的飞洒烦死哒防守打法噶第三方三'},{'name': '张7三', 'src': '/static/image/1.jpg', 'company': '特事特办中国特色一公司','summary': '一群老油条烦死哒范德萨分散发士大夫士大夫是打发发防守打噶第三方三'},{'name': '张8三', 'src': '/static/image/1.jpg', 'company': '特事特办中国特色一公司','summary': '一法撒飞洒的飞洒烦死哒防守打法噶第三方三'},]return render(request,"flow.html",{'user_list':user_list})
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>.container{width: 900px;margin: 0 auto;}.container .item{width: 300px;float: left;}.container .item img{width: 200px;height: 180px;}.container .item p{padding-left: 10px;padding-right: 40px;}</style>
</head>
<body><div class="container">{% for row in user_list %}<div class="item"><img src="{{ row.src }}"><p>{{ row.name }}</p><p>{{ row.summary }}</p></div>{% endfor %}</div>
</body>
</html>

此时显示如下:

很不美观,解决方法,是先将页面分为三个div,让后让图片依次在三个div中排放。

纯静态HTML实现:

<div class="container"><div style="width: 900px;margin: 0 auto;"><div style="width: 280px;float: left;"><div class="item"><img src="{{ user_list.0.src }}"><p>{{ user_list.0.name }}1</p><p>{{ user_list.0.summary }}<br>fdsafdsafd<br>safsdafsd<br>afsdaff<br>assdf</p></div><div class="item"><img src="{{ user_list.0.src }}"><p>{{ user_list.0.name }}4</p><p>{{ user_list.0.summary }}<br>fdsafdsafd<br>safsdafsd<br>afsdaff<br>assdf</p></div></div><div style="width: 280px;float: left;"><div class="item"><img src="{{ user_list.0.src }}"><p>{{ user_list.0.name }}2</p><p>{{ user_list.0.summary }}</p></div><div class="item"><img src="{{ user_list.0.src }}"><p>{{ user_list.0.name }}5</p><p>{{ user_list.0.summary }}<br>fdsafdsafd<br>safsdafsd<br>afsdaff<br>assdf</p></div></div><div style="width: 280px;float: left;"><div class="item"><img src="{{ user_list.0.src }}"><p>{{ user_list.0.name }}3</p><p>{{ user_list.0.summary }}</p></div></div></div></div>

这就实现了瀑布流,使用模板渲染:最初想法如下

       <div style="width: 900px;margin: 0 auto;">{%  for row in user_list %}<div style="width: 300px;float: left;">{% if forloop.counter%3 == 1 %}   {# 这里出错 #}<div class="item"><img src="{{ row.src }}"><p>{{ row.name }}</p><p>{{ row.summary }}</p></div>{% endif %}</div><div style="width: 300px;float: left;">{% if forloop.counter%3 == 2 %}   {# 这里出错 #}<div class="item"><img src="{{ row.src }}"><p>{{ row.name }}</p><p>{{ row.summary }}</p></div>{% endif %}</div><div style="width: 300px;float: left;">{% if forloop.counter%3 == 0 %}   {# 这里出错 #}<div class="item"><img src="{{ row.src }}"><p>{{ row.name }}</p><p>{{ row.summary }}</p></div>{% endif %}</div>{% endfor %}</div>

取模操作%无法在模板中使用,因为使用到了if语句,自定义标签不能用在模板if语句中,所以只能考虑使用过滤器filter:

<div class="container"><div style="width: 300px;float: left">{%  for row in user_list %}{% if forloop.counter|mymod:'3,1' %}<div class="item"><img src="{{ row.src }}"><p>{{ row.name }}{{ forloop.counter }}</p><p>{{ row.summary }}</p></div>{% endif %}{% endfor %}</div><div style="width: 300px;float: left;">{%  for row in user_list %}{% if forloop.counter|mymod:'3,2' %}<div class="item"><img src="{{ row.src }}"><p>{{ row.name }}{{ forloop.counter }}</p><p>{{ row.summary }}</p></div>{% endif %}{% endfor %}</div><div style="width: 300px;float: left;">{%  for row in user_list %}{% if forloop.counter|mymod:'3,0' %}<div class="item"><img src="{{ row.src }}"><p>{{ row.name }}{{ forloop.counter }}</p><p>{{ row.summary }}</p></div>{% endif %}{% endfor %}</div></div>
# 过滤器
from django import templateregister = template.Library()@register.filter
def mymod(v1,v2):n1,n2 = v2.split(',')if v1%int(n1) == int(n2):return Truereturn False

以上是模板渲染,使用了多次的循环,效率不是很好。

使用JS实现,使用Ajax发送一个请求,得到数据,然后在js中进行余数的判断和前端的生成。

二、组合搜索/组合筛选

简单的组合搜索如下图:

建立相应的model:

from django.db import models
# Create your models here.class Level(models.Model):name = models.CharField(max_length=32)def __str__(self):return self.nameclass Category(models.Model):name = models.CharField(max_length=32)def __str__(self):return self.nameclass Video(models.Model):lv = models.ForeignKey(Level,on_delete=models.DO_NOTHING)cg = models.ForeignKey(Category,on_delete=models.DO_NOTHING)title = models.CharField(verbose_name="标题",max_length=64)summary = models.CharField(verbose_name="简介",max_length=128)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)

创建路由项,这里查询的条件组合在路由项中,如下:

path('video-<int:cg_id>-<int:lv_id>.html',views.video,name='video_alais'),

cg_id代表种类的id,lv_id代表级别的id

对应的视图函数:

def video(req,*args,**kwargs):condition = {}for k,v in kwargs.items():if v != 0:condition[k] = vprint(condition)category_list = models.Category.objects.all()level_list = models.Level.objects.all()result = models.Video.objects.filter(**condition)return  render(req,'video.html',{'category_list':category_list,'level_list':level_list,'result':result,'arg_dict':kwargs,})

前端模板文件video.html:

{% load tagandfilter %}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>.filter a {display: inline-block;margin: 5px;padding: 3px 5px;}.filter a.active{background-color: brown;color: white;}</style>
</head>
<body><h1>筛选条件</h1><div class="filter"><div>{% total_tag arg_dict "cg_id" %}:{% for item in category_list %}{% categroy_tag item arg_dict %}{% endfor %}</div><div>{% total_tag arg_dict "lv_id" %}:{% for item in level_list %}{% level_tag item arg_dict %}{% endfor %}</div></div><h1>查询结果</h1><div class="content">{% for item in result %}<div style="width:180px;height:200px;float: left"><img width="150px" height="200px" src="{{ item.img }}"><p>{{ item.title }}</p><p>{{ item.summary }}</p><p>{{ item.create_date }}</p></div>{% endfor %}</div>
</body>
</html>

模板中使用了自定义标签:

@register.simple_tag
def categroy_tag(obj,arg_dict):'''生成种类的A标签:param obj::param arg_dict::return:'''url = reverse("video_alais",kwargs={'cg_id':obj.id,'lv_id':arg_dict.get('lv_id')})if obj.id == arg_dict.get('cg_id'):tag = "<a class='active' href='%s'>%s</a>" %(url,obj.name)return mark_safe(tag)else:tag = "<a  href='%s'>%s</a>" %(url,obj.name)return mark_safe(tag)@register.simple_tag
def level_tag(obj,arg_dict):'''生成级别的A标签:param obj::param arg_dict::return:'''url = reverse("video_alais", kwargs={'lv_id': obj.id, 'cg_id': arg_dict.get('cg_id')})if obj.id == arg_dict.get('lv_id'):tag = "<a class='active' href='%s'>%s</a>" %(url,obj.name)return mark_safe(tag)else:tag = "<a  href='%s'>%s</a>" %(url,obj.name)return mark_safe(tag)@register.simple_tag
def total_tag(arg_dict,key):if key == 'cg_id':url = reverse("video_alais", kwargs={'cg_id': 0, 'lv_id': arg_dict.get('lv_id')})elif key == 'lv_id':url = reverse("video_alais", kwargs={'lv_id': 0, 'cg_id': arg_dict.get('cg_id')})else:url = ""tag = "<a  href='%s'>全部:</a>" %(url)return mark_safe(tag)

增加一个关联表:Direction,与种类表形成多对多关系:

class Direction(models.Model):name = models.CharField(max_length=32)d_2_c = models.ManyToManyField("Category")

使分类根据方向动态变化:大体如下

因为多了一个方向的选择项,路由项修改如下:

path('video2-<int:dr_id>-<int:cg_id>-<int:lv_id>.html',views.video2,name='video_alais2'),

视图函数views.video2:

def video2(req,*args,**kwargs):condition = {}dr_id = kwargs.get('dr_id')cg_id = kwargs.get('cg_id')lv_id = kwargs.get("lv_id")# 可能的请求:# 0-0-0.html 方向、分类、级别都是全部# 1-0-0.html 方向选择了1,分类、级别是全部,此时分类应该根据方向列出有哪些分类# 1-2-0.HTML 方向选择了1,分类选择了2,级别全部;分类先要根据方向列出可能的分类,在根据分类选择video#            还有一种可能,方向选择了1,而1方向对应的分类没有2,此时应该处理成分类为全部,即0direction_list = models.Direction.objects. all()level_list = models.Level.objects.all()if dr_id == 0:# 未选择方向category_list = models.Category.objects.all()if cg_id == 0:pass   # 未选择分类 - 未选择方向else:# 选择了分类 - 未选择方向models.Video.objects.filter(cg_id = cg_id)condition['cg_id'] = cg_idelse:# 选择了方向,将方向对应的分类项查询出来,对象的集合,是QuerySetcategory_list = models.Category.objects.filter(direction=dr_id)# 选取其中的id字段对象集合v = category_list.values_list('id')# print(v.query)  # 打印出查询的SQL语句cg_id_list = list(zip(*v))[0]  # id字段集合形成元组,即(1,2,3)的样子if cg_id == 0:# 未选择分类 - 选择了方向# 这种情况下,选择的条件就是选择全部分类id在cg_id_list元组中的所有video# 即在此方向下的所有分类都要查询出来condition['cg_id__in'] = cg_id_listelse:# 选择了分类,并且分类在cg_id_list中if cg_id in cg_id_list:condition['cg_id'] = cg_idelse:  # 选择了分类,并且分类不在cg_id_list中,这时就选择全部cg_id_list的全部condition['cg_id__in'] = cg_id_listkwargs['cg_id'] = 0if lv_id != 0:  # 级别是单独的condition['lv_id'] = lv_idresult = models.Video.objects.filter(**condition)  # 根据条件最终查询的video结果集合return  render(req,'video2.html',{'direction_list':direction_list,'category_list':category_list,'level_list':level_list,'result':result,'arg_dict':kwargs,})

前端模板video2.html

{% load tagandfilter %}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>.filter a {display: inline-block;margin: 5px;padding: 3px 5px;}.filter a.active{background-color: brown;color: white;}</style>
</head>
<body><h1>筛选条件</h1><div class="filter"><div>{% total_tag_2 arg_dict "dr_id" %}{% for item in direction_list %}<!-- if kwargs.dr_id = item.id加入样式else:没有样式-->{% dr_tag item arg_dict %}{% endfor %}</div><div>{% total_tag_2 arg_dict "cg_id" %}{% for item in category_list %}{% cg_tag item arg_dict %}{% endfor %}</div><div>{% total_tag_2 arg_dict "lv_id" %}{% for item in level_list %}{% lv_tag item arg_dict %}{% endfor %}</div></div><h1>查询结果</h1><div class="content">{% for item in result %}<div style="width:180px;height:200px;float: left"><img width="150px" height="200px" src="{{ item.img }}"><p>{{ item.title }}</p><p>{{ item.summary }}</p><p>{{ item.create_date }}</p></div>{% endfor %}</div>
</body>
</html>

自定义的标签:

@register.simple_tag
def dr_tag(obj,arg_dict):'''生成A标签:param obj::param arg_dict::return:'''url = reverse('video_alais2',kwargs={'dr_id':obj.id,'cg_id':arg_dict.get('cg_id'),'lv_id':arg_dict.get('lv_id')})if obj.id == arg_dict.get('dr_id'):tag = "<a class='active' href='%s'>%s</a>" %(url,obj.name)return mark_safe(tag)else:tag = "<a  href='%s'>%s</a>" %(url,obj.name)return mark_safe(tag)@register.simple_tag
def cg_tag(obj,arg_dict):'''生成A标签:param obj::param arg_dict::return:'''url = reverse('video_alais2',kwargs={'dr_id':arg_dict.get('dr_id'),'cg_id':obj.id,'lv_id':arg_dict.get('lv_id')})if obj.id == arg_dict.get('cg_id'):tag = "<a class='active' href='%s'>%s</a>" %(url,obj.name)return mark_safe(tag)else:tag = "<a  href='%s'>%s</a>" %(url,obj.name)return mark_safe(tag)@register.simple_tag
def lv_tag(obj,arg_dict):'''生成A标签:param obj::param arg_dict::return:'''url = reverse('video_alais2',kwargs={'dr_id':arg_dict.get('dr_id'),'cg_id':arg_dict.get('cg_id'),'lv_id':obj.id})if obj.id == arg_dict.get('lv_id'):tag = "<a class='active' href='%s'>%s</a>" %(url,obj.name)return mark_safe(tag)else:tag = "<a  href='%s'>%s</a>" %(url,obj.name)return mark_safe(tag)@register.simple_tag
def total_tag_2(arg_dict,key):if key == 'dr_id':url = reverse("video_alais2", kwargs={'dr_id':0,'cg_id': arg_dict.get('cg_id'), 'lv_id': arg_dict.get('lv_id')})elif key == 'cg_id':url = reverse("video_alais2", kwargs={'dr_id': arg_dict.get('dr_id'), 'cg_id': 0, 'lv_id': arg_dict.get('lv_id')})elif key == 'lv_id':url = reverse("video_alais2", kwargs={'dr_id':arg_dict.get('dr_id'),'lv_id': 0, 'cg_id': arg_dict.get('cg_id')})else:url = ""if arg_dict.get(key) == 0:tag = "<a  class='active' href='%s'>全部:</a>" %(url,)else:tag = "<a  href='%s'>全部:</a>" % (url,)return mark_safe(tag)

主要的环节是逻辑上根据方向、分类、级别的选择,动态显示各个项,然后在综合条件下选择出video。

Python入门自学进阶-Web框架——33、瀑布流布局与组合查询相关推荐

  1. Python入门自学进阶-Web框架——8、认识Ajax,与Django交互,基于jQuery

    基于jQuery的Ajax实现: jQquery中创建XMLHttpRequest对象就没有兼容性问题了,而且不需要前面的四个步骤,直接使用$.ajax(),通过设置相关的参数,如提交的方法,url, ...

  2. Python入门自学进阶-Web框架——34、富文本编辑器KindEditor、爬虫初步

    KindEditor是一个轻量级的富文本编辑器,应用于浏览器客户端. 一.首先是下载:http://kindeditor.net/down.php,如下图 下载后是 解压缩后: 红框选中的都可以删除到 ...

  3. Python入门自学进阶-Web框架——16、Django登录/注册

    以抽屉为原型,实现用户的注册和登录. 基本的界面: 第一个知识点:自动发送验证码到邮箱,也就是实现自动发送邮件的功能: 要自动给别人发送邮件,首先要有自己的邮箱,msg["From" ...

  4. Python入门自学进阶——9-网络编程-远程执行命令

    远程执行命令 类似远程终端,输入一个命令,在对端执行.也是网络通信编程的典型应用. socket连接都是一样的,发送内容也是一样的,不同之处是,对端拿到的内容,当做命令执行,然后,将执行的结果反馈给对 ...

  5. Python入门自学进阶——11-协程

    协程,又叫做微线程,纤程.Coroutine.协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈,调度切换时,将寄存器上下文和栈保存,在切换回来时,恢复寄存器山下文和栈.协程能保留上一次调 ...

  6. python入门与进阶

    title: python入门与进阶 categories: python tags: [python] python入门导学 python的特点 是面向对象的编程语言 简介,灵活,优雅,哲学 易于上 ...

  7. Python入门及进阶

    Python入门及进阶 一.python是什么? 二.python基础知识 三.python面向对象 四.文件处理 一.python是什么? python是一种跨平台.解释性.面向对象的高级编程语言. ...

  8. 自学python要看哪些书籍-Python入门自学到精通需要看哪些书籍?

    Python语言在近几年可以算得上如日中天,越来越火爆的同时,学习Python的人也越来越多了.对于不同基础的学习者来讲,学习的重点和方式也许会有差别,但是基础语法永远都是重中之重.在牢牢掌握基础知识 ...

  9. 『Python学习笔记』Python中的异步Web框架之fastAPI介绍RestAPI

    Python中的异步Web框架之fastAPI介绍&RestAPI 文章目录 一. fastAPI简要介绍 1.1. 安装 1.2. 创建 1.3. get方法 1.4. post方法 1.5 ...

最新文章

  1. 热门 | Google Brain前员工深度盘点2017人工智能和深度学习各大动态
  2. 独家 | 盘点9个适用所有学科的R数据可视化包(附链接)
  3. 【学时总结】 ◆学时·III◆ 二分图
  4. golang strings Replace 字符串替换
  5. spring控制并发数的工具类ConcurrencyThrottleSupport和ConcurrencyThrottleInterceptor
  6. 研究SAP service order status存储字段
  7. Java工具类——通过配置XML验证Map
  8. RewriteCond 详解
  9. Python中的实用小技巧,可以省下不是事情,喜欢记得收下
  10. TCP/IP参考模型和五层参考模型
  11. 常用的比较排序算法总结
  12. 【信息系统项目管理师】第2章-信息系统项目管理基础 知识点详细整理
  13. 行政管理专业考计算机研究生分数,行政管理学,考研,历年分数线是多少?
  14. 博思英语计算机考试,博思英语考试经验及答题技巧
  15. 海湾汉字编码表全部_汉字区位码对照查询表-汉字区位码对照表大全下载pdf打印版-西西软件下载...
  16. FLV转MPG和转成其它格式的转码方法
  17. android外设键盘按键映射表
  18. C#数据库教程5-ADO.NET登录页面设计
  19. matlab中cuk电路搭建,cuk电路matlab仿真
  20. 【翠花学Maven】Maven详解

热门文章

  1. 记录一次爬虫接单项目【采集国际淘宝数据】
  2. 表单(四)表单序列化
  3. Java-Python对比学习之构造器
  4. 新闻编辑html,移动互联网环境下HTML5新闻编辑特点分析.doc
  5. 魅族路由器极速版刷机_好先生追剧神器 魅族路由器极速版评测
  6. 在校园管理方面人脸识别有哪些应用场景
  7. 硬件除法器原理_[ECCamp;RSA]除法器
  8. Spring Data Redis 正确使用姿势
  9. 杂项:SpagoBI
  10. 达梦数据库(DM)——配置达梦数据库外部链接——DM到DM的外部链接创建