【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>
前端页面
最新文章
- 【转载】C#怎么判断字符是不是汉字
- android 图片压缩
- 挑战程序2.1.5 穷竭搜索>;>;宽度优先搜索
- Spark大数据的学习历程
- 算法(三)粒子群算法PSO的介绍
- 搭建Asp.Net MVC4
- Unity基本操作一
- SharePoint Server 2010安装图解
- javax.mail用smtp服务器发送带附件的邮件
- PHP实现类似于MySQ L的group by 效果
- Openstack(企业私有云)万里长征第一步——安装
- SpringMVC——请求映射
- 关于Win7 内存变小处理方法
- 【Python】 hash值计算 hashlib &; hmac
- 洛谷P2042 [NOI2005]维护数列
- emacs 文本替换
- Android O广播接收情况
- 自适应:用JS做的自适应,是最差的自适应,记页面刷新前后尺寸变化
- you-get模块
- git常用命令及用法小计
热门文章
- Spring MVC <;context:annotation-config>; 与 <;context:component-scan>;
- MyEclipse10.0 采用插件方式安装 SVN
- splice与slice区别
- angular-file-upload.min.js.map文件下载
- VUE【二、选项和生命周期】
- 解决织梦5.7添加新变量出现:Request var not allow!的办法
- 【Day4】1.JsonPath使用案例
- JEESZ-SSO解决方案
- 《设计模式之美》 <;02>;评判代码质量好坏的维度
- Django_06_项目完成