【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-->字节码 低级语言: ...
随机推荐
- django类视图的使用
1 类视图引入 以函数的方式定义的视图称为函数视图,函数视图便于理解. 但是遇到一个视图对应的路径提供了多种不同HTTP请求方式的支持时,便需要在一个函数中编写不同的业务逻辑,代码可读性与复用性都不佳 ...
- command not found 的解决&&解释
ln -s /opt/platform/calico/calicoctl /usr/local/sbin/calicoctl ln -s /opt/platform/nginx/sbin/nginxl ...
- MySQL Select语句的执行顺序
源文章:How is a query executed in MySQL? 当执行SQL的Select查询语句时,SQL指令的执行顺序如下: FROM 子句 WHERE 子句 GROUP BY 子句 ...
- mysql 8.0.13开启远程连接 配置方式
1:linux登录mysql [root@localhost mysql]# mysql -u root -p Enter password: Welcome to the MySQL monitor ...
- C#动态生成Word文档并填充数据
C#也能动态生成Word文档并填充数据 http://www.cnblogs.com/qyfan82/archive/2007/09/14/893293.html 引用http://blog.csdn ...
- springboot 服务端获取前端传过来的参数7种方式
下面为7种服务端获取前端传过来的参数的方法 1.直接把表单的参数写在Controller相应的方法的形参中,适用于GET 和 POST请求方式 这种方式不会校验请求里是否带参数,即下面的userna ...
- docker-compose deploy replicaSet in standalone MongoDB cluster and with auth
经过两天的折腾,终于实现了自己想要的效果,就是通过docker-compose 部署最新的mongodb replicaSet, 主要是为了测试 4.2 最新的多文档事务,下面将整个步骤分享一下: d ...
- 开源跨境ERP - 小老板 Docker/Docker Compose一键部署
先上部署成功后的截图,各个菜单点击均无报错 DockerCompose 包含: 1. 三个mysql5.7数据库 2. redis php会话存储+ memcached 3. 小老板php主程序 do ...
- 什么是TCP/IP协议和举例
一张图+说明,彻底理解TCP/IP协议是个什么玩意儿! 相关图片:https://www.cnblogs.com/andy9468/p/10096606.html 说明:1.应用层常见协议或命令:HT ...
- 学习手写vue,理解原理
class Compiler{ constructor(el,vm){ // 判断el属性 是不是 一个元素, 如果不是就获取 this.el = this.isElementNode(el)?el: ...