【Python之路】特别篇--Django瀑布流实现
瀑布流
瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。最早采用此布局的网站是Pinterest,逐渐在国内流行开来。国内大多数清新站基本为这类风格。
实现效果:
数据存放方式:
实现方式一: 自定义模版语言(simple_tag)
思路: 后端获取数据,,前端页面使用自定义模板语言,实现第一条数据放第一个div,...,(通过求余数实现),返回标签字符串,页面显示.
实现方法:
1.在app中创建templatetags模块
2.创建任意 .py 文件,如:newtag.py
- from django import template
- from django.utils.safestring import mark_safe
- register = template.Library()
3.后台获取数据
- def student(request):
- queryset_dict = models.StudentDetail.objects.filter(student__status=1).values('letter_of_thanks','student__name','student__pic','student__company','student__salary')
- return render(request,'home.html',{'queryset_dict':queryset_dict})
4.前端使用模板语言 for循环得到每一个item数据
- <div style="width: 245px;float: left">
- {% for item in queryset_dict %}
- ....
- {% endfor %}
- </div>
5.自定义模版语言,
实现:传入item数据 , 当前循环的次数 , => 通过次数 , 求余判断, 数据放在div1 还是div2 ,.... ,
- @register.simple_tag
- def image_show(item,counter,allcount,remainder):
- '''
- :param item: 当前循环获取的数据
- :param counter: 当前循环次数(模版语言for循环默认从1开始)
- :param allcount: 页面分布列数
- :param remainder: 余数
- :return:
- '''
- TEMP = '''
- <div style="width: 245px;" >
- <img src="/%s" alt="" style="width: 245px;height: 250px">
- <p>%s</p>
- <p>%s</p>
- </div>
- '''
- if counter%allcount == remainder:
- TEMP = TEMP %(item['student__pic'],
- item['student__name'],
- item['letter_of_thanks'],
- )
- return mark_safe(TEMP)
- else:
- return ''
注意:模版语言默认会返回None , 所以要设置返回空字符串
6.前端调用:
- <div style="width: 245px;float: left">
- {% for item in queryset_dict %}
- {% image_show item forloop.counter 4 1 %}
- {% endfor %}
- </div>
forloop.counter 获取当前循环的次数 (默认从1开始递增!)
7.div2,div3,div4 同上
完整代码:
- from django import template
- from django.utils.safestring import mark_safe
- register = template.Library()
- @register.simple_tag
- def image_show(item,counter,allcount,remainder):
- '''
- :param item: 当前循环获取的数据
- :param counter: 当前循环次数(模版语言for循环默认从1开始)
- :param allcount: 页面分布列数
- :param remainder: 余数
- :return:
- '''
- TEMP = '''
- <div style="width: 245px;" >
- <img src="/%s" alt="" style="width: 245px;height: 250px">
- <p>%s</p>
- <p>%s</p>
- </div>
- '''
- if counter%allcount == remainder:
- TEMP = TEMP %(item['student__pic'],
- item['student__name'],
- item['letter_of_thanks'],
- )
- return mark_safe(TEMP)
- else:
- return ''
自定义模版语言
- {% load newtag %}
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <style>
- .clearfix:after{
- content: 'x';
- height: 0;
- visibility: hidden;
- clear: both;
- display: block;
- }
- .stu{
- margin:0 auto;
- width: 980px;
- }
- </style>
- </head>
- <body>
- <div class="clearfix stu">
- <div style="width: 245px;float: left">
- {% for item in queryset_dict %}
- {% image_show item forloop.counter 4 1 %}
- {% endfor %}
- </div>
- <div style="width: 245px;float: left">
- {% for item in queryset_dict %}
- {% image_show item forloop.counter 4 2 %}
- {% endfor %}
- </div>
- <div style="width: 245px;float: left">
- {% for item in queryset_dict %}
- {% image_show item forloop.counter 4 3 %}
- {% endfor %}
- </div>
- <div style="width: 245px;float: left">
- {% for item in queryset_dict %}
- {% image_show item forloop.counter 4 0 %}
- {% endfor %}
- </div>
- </div>
- </body>
- </html>
前端页面
实现方式二: 自定义模版语言(filter)
区别:
1.自定义的模版语言使用filter 而不是simple_tag
2.自定义的filter 支持if 条件判断来使用! , 而 simple_tag不支持
- {% if filter模版语言返回结果 %}
- ...
- {% endif %}
- 或 {{ filter模版语言 }}
前端设计思路:
1.如果if条件 满足,则把数据填充在该div上.
- <div style="width: 245px;float: left">
- {% for item in queryset_dict %}
- {% if filter模版语言返回结果 %}
- <div style="width: 245px;" >
- <img src="/{{ item.student__pic }}" alt="" style="width: 245px;height: 250px">
- <p>{{ item.student__name }}</p>
- <p>{{ item.letter_of_thanks }}</p>
- </div>
- {% endif %}
- {% endfor %}
- </div>
2.filter 用法:
默认只允许 传入2个参数,如果传入参数过多,就传入字符串,然后分割!
- @register.filter
- def image_show2(value,arg):
- countet = value # 当前for循环次数
- allcount = int(arg.split(',')[0]) # 前端页面列数
- remainder = int(arg.split(',')[1]) # 余数
- if countet%allcount == remainder:
- return True
- else:
- return False
3.filter使用方法:
- {{ 参数1 | filter :参数2 }}
4.前端页面:
- <div style="width: 245px;float: left">
- {% for item in queryset_dict %}
- {% if forloop.counter|image_show2:"4,0" %}
- <div style="width: 245px;" >
- <img src="/{{ item.student__pic }}" alt="" style="width: 245px;height: 250px">
- <p>{{ item.student__name }}</p>
- <p>{{ item.letter_of_thanks }}</p>
- </div>
- {% endif %}
- {% endfor %}
- </div>
注意: img标签的 src 地址斜杠 /
实现方式三: JQ中Ajax实现
设计思路:
1.访问页面,
2.自动发送ajax请求
3.ajax获取数据
4.求余判断,生成标签.页面添加标签
实现方法:
1.后台判断,Ajax发送的POST请求, => 数据库查询获取数据,
- def student1(request):
- if request.method == 'POST':
- queryset_dict = models.StudentDetail.objects.filter(student__status=1).values('letter_of_thanks',
- 'student__name', 'student__pic',
- 'student__company',
- 'student__salary')
- queryset_list = list(queryset_dict)
- return HttpResponse(json.dumps(queryset_list))
- else:
- return render(request,'student.html')
注意: 后台获取的数据形式为 QuerySet[{数据1},{数据2}] , 需要先转换成列表形式 再json.dumps()
2.json返回前端.
3.前端JQ创建标签,填充数据,把标签添加到div1,div2,...上
- $.each(data,function (k,v) {
- k = k + 1;
- var div = document.createElement('div');
- div.className ='item';
- var img = document.createElement('img');
- img.src='/'+v.student__pic;
- var p1 = document.createElement('p');
- p1.innerText = v.letter_of_thanks;
- div.appendChild(img);
- div.appendChild(p1);
- if(k%4 == 1){
- $('#container').children(':eq(0)').append(div);
- }else if(k%4 == 2){
- $('#container').children(':eq(1)').append(div);
- }else if(k%4 == 3){
- $('#container').children(':eq(2)').append(div);
- }else if(k%4 == 0){
- $('#container').children(':eq(3)').append(div);
- }else {
- console.log('error')
- }
- })
完整代码:
- from django.shortcuts import render,HttpResponse
- import json
- # Create your views here.
- from app01 import models
- def student1(request):
- if request.method == 'POST':
- queryset_dict = models.StudentDetail.objects.filter(student__status=1).values('letter_of_thanks',
- 'student__name', 'student__pic',
- 'student__company',
- 'student__salary')
- queryset_list = list(queryset_dict)
- return HttpResponse(json.dumps(queryset_list))
- else:
- return render(request,'student.html')
后台代码
- {% load newtag %}
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <style>
- .clearfix:after{
- content: 'x';
- height: 0;
- visibility: hidden;
- clear: both;
- display: block;
- }
- .stu{
- margin:0 auto;
- width: 980px;
- }
- .item{
- width:245px;
- }
- .item img{
- width: 245px;
- height: 250px;
- }
- </style>
- </head>
- <body>
- <div class="clearfix stu" id="container">
- <div style="width: 245px;float: left">
- </div>
- <div style="width: 245px;float: left">
- </div>
- <div style="width: 245px;float: left">
- </div>
- <div style="width: 245px;float: left">
- </div>
- </div>
- <script src="/static/js/jquery-2.1.4.min.js"></script>
- <script>
- $(function () {
- $.ajax({
- url:'/student1/',
- type:'POST',
- dataType:'json',
- success:function (data) {
- console.log('ok');
- console.log(data);
- $.each(data,function (k,v) {
- k = k + 1;
- var div = document.createElement('div');
- div.className ='item';
- var img = document.createElement('img');
- img.src='/'+v.student__pic;
- var p1 = document.createElement('p');
- var p2 = document.createElement('p');
- p1.innerText = v.student__name;
- p2.innerText = v.letter_of_thanks;
- div.appendChild(img);
- div.appendChild(p1);
- div.appendChild(p2);
- console.log(div);
- if(k%4 == 1){
- $('#container').children(':eq(0)').append(div);
- }else if(k%4 == 2){
- $('#container').children(':eq(1)').append(div);
- }else if(k%4 == 3){
- $('#container').children(':eq(2)').append(div);
- }else if(k%4 == 0){
- $('#container').children(':eq(3)').append(div);
- }else {
- console.log('error')
- }
- })
- }
- })
- })
- </script>
- </body>
- </html>
前端页面
【Python之路】特别篇--Django瀑布流实现的更多相关文章
- 【Python之路】特别篇--Django生产环境部署
Django的部署可以有很多方式,采用nginx+uwsgi的方式是其中比较常见的一种方式. uWSGI uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中H ...
- python之路基础篇
基础篇 1.Python基础之初识python 2.Python数据类型之字符串 3.Python数据类型之列表 4.Python数据类型之元祖 5.Python数据类型之字典 6.Python Se ...
- python之路入门篇
一. Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,Guido开始写能够解释Python语言语法的解释器.Python这个名字,来 ...
- python之路——基础篇(2)模块
模块:os.sys.time.logging.json/pickle.hashlib.random.re 模块分为三种: 自定义模块 第三方模块 内置模块 自定义模块 1.定义模块 将一系列功能函数或 ...
- python之路第一篇
一.python环境的搭建 1.window下环境的搭建 (1).在 https://www.python.org/downloads/ 下载自己系统所需要的python版本 (2).安装python ...
- python之路第二篇(基础篇)
入门知识: 一.关于作用域: 对于变量的作用域,执行声明并在内存中存在,该变量就可以在下面的代码中使用. if 10 == 10: name = 'allen' print name 以下结论对吗? ...
- Python之路(第九篇)Python文件操作
一.文件的操作 文件句柄 = open('文件路径+文件名', '模式') 例子 f = open("test.txt","r",encoding = “utf ...
- Python之路(第二篇):Python基本数据类型字符串(一)
一.基础 1.编码 UTF-8:中文占3个字节 GBK:中文占2个字节 Unicode.UTF-8.GBK三者关系 ascii码是只能表示英文字符,用8个字节表示英文,unicode是统一码,世界通用 ...
- Python之路(第一篇):Python简介和基础
一.开发简介 1.开发: 开发语言: 高级语言:python.JAVA.PHP.C#..ruby.Go-->字节码 低级语言: ...
随机推荐
- ES使用小结之索引Rollover
Elasticsearch 使用小结之索引Rollover 索引名 一般而言,客户端将数据每天写入一个索引,比如直接写入YYYY-MM-HH格式的索引,那么我们只需要在写入的客户端里面获取时间,然后得 ...
- QT 线程的使用(继承QThread)
对于多线程而言,要注意资源的同步和互斥问题,但对于单独的一个线程,则只需要对它的run方法进行重写. 下面实现了一个简单的线程 widget.h文件 #ifndef WIDGET_H #define ...
- python学习-7 条件语句 while循环 + 练习题
1.死循环 while 1 == 1: print('ok') 结果是一直循环 2.循环 count = 0 while count < 10: print(count) count = cou ...
- Java手写简单Linkedlist一(包括增加,插入,查找,toString,remove功能)
@Java300 学习总结 一.自定义节点 LinkList底层为双向链表.特点为查询效率低,但增删效率高,线程不安全. 链表数据储存在节点,且每个节点有指向上个和下个节点的指针. 创建ggLinke ...
- js 超浓缩 双向绑定
绑定确实是个有趣的话题. 现在我的绑定器有了不少的功能 1. 附着在Object对象上,一切以对象为中心 2. 与页面元素进行双向绑定 3. 与任意对象绑定,主要是应用在绑定到页面元素的一些属性上,比 ...
- OPENGL 显示BMP图片+旋转
VS2010/Windows 7/ 1. 需包含头文件 stdio.h, glaux.h, glut.h.需要对应的lib,并添加包含路径 2. 窗口显示用glut库的函数 3. bmp图片从本地读取 ...
- 系统性能分析-vmstat命令详解
最近温馨巩固Linux 操作系统的 vmstat命令,这个命令所能打印的系统信息满多的,比较好用,就顺当记录下重要的点,方便以后排查系统问题时拿出来用 字段 含义 procs 进程信息字段: -r:正 ...
- 复选框已经有checked,但是页面没有选中效果(解决)
原代码: $("#checked").click(function(){ $(".input[name="checked"]").attr( ...
- SQL优化的总结和一些避免全盘扫描的注意事项
1.应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描. 2.应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一 ...
- eclipse debug 调试找不到资源问题解决
eclipse debug 的时候,如果使用maven bulid,就可能找不到class,这种情况就需要先停止服务,然后配置 Run configurations-Source,然后remove掉D ...