瀑布流

  瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。最早采用此布局的网站是Pinterest,逐渐在国内流行开来。国内大多数清新站基本为这类风格。

实现效果:

数据存放方式:

实现方式一: 自定义模版语言(simple_tag)

思路: 后端获取数据,,前端页面使用自定义模板语言,实现第一条数据放第一个div,...,(通过求余数实现),返回标签字符串,页面显示.

实现方法:

1.在app中创建templatetags模块

2.创建任意 .py 文件,如:newtag.py

  1. from django import template
  2. from django.utils.safestring import mark_safe
  3.  
  4. register = template.Library()

3.后台获取数据

  1. def student(request):
  2. queryset_dict = models.StudentDetail.objects.filter(student__status=1).values('letter_of_thanks','student__name','student__pic','student__company','student__salary')
  3.  
  4. return render(request,'home.html',{'queryset_dict':queryset_dict})

4.前端使用模板语言 for循环得到每一个item数据

  1. <div style="width: 245px;float: left">
  2. {% for item in queryset_dict %}
  3. ....
  4. {% endfor %}
  5. </div>

5.自定义模版语言,

实现:传入item数据 , 当前循环的次数 , => 通过次数 , 求余判断, 数据放在div1 还是div2 ,.... ,

  1. @register.simple_tag
  2. def image_show(item,counter,allcount,remainder):
  3. '''
  4. :param item: 当前循环获取的数据
  5. :param counter: 当前循环次数(模版语言for循环默认从1开始)
  6. :param allcount: 页面分布列数
  7. :param remainder: 余数
  8. :return:
  9. '''
  10. TEMP = '''
  11. <div style="width: 245px;" >
  12. <img src="/%s" alt="" style="width: 245px;height: 250px">
  13. <p>%s</p>
  14. <p>%s</p>
  15. </div>
  16. '''
  17. if counter%allcount == remainder:
  18. TEMP = TEMP %(item['student__pic'],
  19. item['student__name'],
  20. item['letter_of_thanks'],
  21. )
  22. return mark_safe(TEMP)
  23. else:
  24. return ''

注意:模版语言默认会返回None , 所以要设置返回空字符串

6.前端调用:

  1. <div style="width: 245px;float: left">
  2. {% for item in queryset_dict %}
  3. {% image_show item forloop.counter 4 1 %}
  4. {% endfor %}
  5. </div>

forloop.counter 获取当前循环的次数 (默认从1开始递增!)

7.div2,div3,div4 同上

完整代码:

  1. from django import template
  2. from django.utils.safestring import mark_safe
  3.  
  4. register = template.Library()
  5.  
  6. @register.simple_tag
  7. def image_show(item,counter,allcount,remainder):
  8. '''
  9. :param item: 当前循环获取的数据
  10. :param counter: 当前循环次数(模版语言for循环默认从1开始)
  11. :param allcount: 页面分布列数
  12. :param remainder: 余数
  13. :return:
  14. '''
  15.  
  16. TEMP = '''
  17. <div style="width: 245px;" >
  18. <img src="/%s" alt="" style="width: 245px;height: 250px">
  19. <p>%s</p>
  20. <p>%s</p>
  21. </div>
  22. '''
  23. if counter%allcount == remainder:
  24. TEMP = TEMP %(item['student__pic'],
  25. item['student__name'],
  26. item['letter_of_thanks'],
  27. )
  28. return mark_safe(TEMP)
  29. else:
  30. return ''

自定义模版语言

  1. {% load newtag %}
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Title</title>
  7. <style>
  8. .clearfix:after{
  9. content: 'x';
  10. height: 0;
  11. visibility: hidden;
  12. clear: both;
  13. display: block;
  14. }
  15. .stu{
  16. margin:0 auto;
  17. width: 980px;
  18. }
  19. </style>
  20. </head>
  21. <body>
  22.  
  23. <div class="clearfix stu">
  24. <div style="width: 245px;float: left">
  25. {% for item in queryset_dict %}
  26. {% image_show item forloop.counter 4 1 %}
  27. {% endfor %}
  28. </div>
  29. <div style="width: 245px;float: left">
  30. {% for item in queryset_dict %}
  31. {% image_show item forloop.counter 4 2 %}
  32. {% endfor %}
  33. </div>
  34. <div style="width: 245px;float: left">
  35. {% for item in queryset_dict %}
  36. {% image_show item forloop.counter 4 3 %}
  37. {% endfor %}
  38. </div>
  39. <div style="width: 245px;float: left">
  40. {% for item in queryset_dict %}
  41. {% image_show item forloop.counter 4 0 %}
  42. {% endfor %}
  43. </div>
  44. </div>
  45. </body>
  46. </html>

前端页面

实现方式二: 自定义模版语言(filter)

区别:

1.自定义的模版语言使用filter 而不是simple_tag

2.自定义的filter 支持if 条件判断来使用! , 而 simple_tag不支持

  1. {% if filter模版语言返回结果 %}
  2. ...
  3. {% endif %}
  4.  
  5. {{ filter模版语言 }}

前端设计思路:

1.如果if条件 满足,则把数据填充在该div上.

  1. <div style="width: 245px;float: left">
  2. {% for item in queryset_dict %}
  3. {% if filter模版语言返回结果 %}
  4. <div style="width: 245px;" >
  5. <img src="/{{ item.student__pic }}" alt="" style="width: 245px;height: 250px">
  6. <p>{{ item.student__name }}</p>
  7. <p>{{ item.letter_of_thanks }}</p>
  8. </div>
  9. {% endif %}
  10. {% endfor %}
  11. </div>

2.filter 用法:

默认只允许 传入2个参数,如果传入参数过多,就传入字符串,然后分割!

  1. @register.filter
  2. def image_show2(value,arg):
  3.  
  4. countet = value # 当前for循环次数
  5. allcount = int(arg.split(',')[0]) # 前端页面列数
  6. remainder = int(arg.split(',')[1]) # 余数
  7. if countet%allcount == remainder:
  8. return True
  9. else:
  10. return False

3.filter使用方法:

  1. {{ 参数1 | filter :参数2 }}

4.前端页面:

  1. <div style="width: 245px;float: left">
  2. {% for item in queryset_dict %}
  3. {% if forloop.counter|image_show2:"4,0" %}
  4. <div style="width: 245px;" >
  5. <img src="/{{ item.student__pic }}" alt="" style="width: 245px;height: 250px">
  6. <p>{{ item.student__name }}</p>
  7. <p>{{ item.letter_of_thanks }}</p>
  8. </div>
  9. {% endif %}
  10. {% endfor %}
  11. </div>

注意: img标签的 src 地址斜杠 /

实现方式三: JQ中Ajax实现

设计思路:

1.访问页面,

2.自动发送ajax请求

3.ajax获取数据

4.求余判断,生成标签.页面添加标签

实现方法:

1.后台判断,Ajax发送的POST请求, => 数据库查询获取数据,

  1. def student1(request):
  2.  
  3. if request.method == 'POST':
  4. queryset_dict = models.StudentDetail.objects.filter(student__status=1).values('letter_of_thanks',
  5. 'student__name', 'student__pic',
  6. 'student__company',
  7. 'student__salary')
  8. queryset_list = list(queryset_dict)
  9.  
  10. return HttpResponse(json.dumps(queryset_list))
  11. else:
  12. return render(request,'student.html')

注意: 后台获取的数据形式为 QuerySet[{数据1},{数据2}] , 需要先转换成列表形式 再json.dumps()

2.json返回前端.

3.前端JQ创建标签,填充数据,把标签添加到div1,div2,...上

  1. $.each(data,function (k,v) {
  2. k = k + 1;
  3.  
  4. var div = document.createElement('div');
  5. div.className ='item';
  6. var img = document.createElement('img');
  7. img.src='/'+v.student__pic;
  8. var p1 = document.createElement('p');
  9. p1.innerText = v.letter_of_thanks;
  10. div.appendChild(img);
  11. div.appendChild(p1);
  12.  
  13. if(k%4 == 1){
  14. $('#container').children(':eq(0)').append(div);
  15. }else if(k%4 == 2){
  16. $('#container').children(':eq(1)').append(div);
  17. }else if(k%4 == 3){
  18. $('#container').children(':eq(2)').append(div);
  19. }else if(k%4 == 0){
  20. $('#container').children(':eq(3)').append(div);
  21. }else {
  22. console.log('error')
  23. }
  24. })

完整代码:

  1. from django.shortcuts import render,HttpResponse
  2. import json
  3.  
  4. # Create your views here.
  5. from app01 import models
  6.  
  7. def student1(request):
  8.  
  9. if request.method == 'POST':
  10. queryset_dict = models.StudentDetail.objects.filter(student__status=1).values('letter_of_thanks',
  11. 'student__name', 'student__pic',
  12. 'student__company',
  13. 'student__salary')
  14. queryset_list = list(queryset_dict)
  15.  
  16. return HttpResponse(json.dumps(queryset_list))
  17. else:
  18. return render(request,'student.html')

后台代码

  1. {% load newtag %}
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Title</title>
  7. <style>
  8. .clearfix:after{
  9. content: 'x';
  10. height: 0;
  11. visibility: hidden;
  12. clear: both;
  13. display: block;
  14. }
  15. .stu{
  16. margin:0 auto;
  17. width: 980px;
  18. }
  19. .item{
  20. width:245px;
  21. }
  22. .item img{
  23. width: 245px;
  24. height: 250px;
  25. }
  26. </style>
  27. </head>
  28. <body>
  29.  
  30. <div class="clearfix stu" id="container">
  31. <div style="width: 245px;float: left">
  32.  
  33. </div>
  34. <div style="width: 245px;float: left">
  35.  
  36. </div>
  37. <div style="width: 245px;float: left">
  38.  
  39. </div>
  40. <div style="width: 245px;float: left">
  41.  
  42. </div>
  43. </div>
  44.  
  45. <script src="/static/js/jquery-2.1.4.min.js"></script>
  46. <script>
  47. $(function () {
  48. $.ajax({
  49. url:'/student1/',
  50. type:'POST',
  51. dataType:'json',
  52. success:function (data) {
  53. console.log('ok');
  54. console.log(data);
  55. $.each(data,function (k,v) {
  56. k = k + 1;
  57.  
  58. var div = document.createElement('div');
  59. div.className ='item';
  60. var img = document.createElement('img');
  61. img.src='/'+v.student__pic;
  62. var p1 = document.createElement('p');
  63. var p2 = document.createElement('p');
  64. p1.innerText = v.student__name;
  65. p2.innerText = v.letter_of_thanks;
  66. div.appendChild(img);
  67. div.appendChild(p1);
  68. div.appendChild(p2);
  69. console.log(div);
  70. if(k%4 == 1){
  71. $('#container').children(':eq(0)').append(div);
  72. }else if(k%4 == 2){
  73. $('#container').children(':eq(1)').append(div);
  74. }else if(k%4 == 3){
  75. $('#container').children(':eq(2)').append(div);
  76. }else if(k%4 == 0){
  77. $('#container').children(':eq(3)').append(div);
  78. }else {
  79. console.log('error')
  80. }
  81. })
  82. }
  83. })
  84. })
  85.  
  86. </script>
  87. </body>
  88. </html>

前端页面

【Python之路】特别篇--Django瀑布流实现的更多相关文章

  1. 【Python之路】特别篇--Django生产环境部署

    Django的部署可以有很多方式,采用nginx+uwsgi的方式是其中比较常见的一种方式. uWSGI uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中H ...

  2. python之路基础篇

    基础篇 1.Python基础之初识python 2.Python数据类型之字符串 3.Python数据类型之列表 4.Python数据类型之元祖 5.Python数据类型之字典 6.Python Se ...

  3. python之路入门篇

    一. Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,Guido开始写能够解释Python语言语法的解释器.Python这个名字,来 ...

  4. python之路——基础篇(2)模块

    模块:os.sys.time.logging.json/pickle.hashlib.random.re 模块分为三种: 自定义模块 第三方模块 内置模块 自定义模块 1.定义模块 将一系列功能函数或 ...

  5. python之路第一篇

    一.python环境的搭建 1.window下环境的搭建 (1).在 https://www.python.org/downloads/ 下载自己系统所需要的python版本 (2).安装python ...

  6. python之路第二篇(基础篇)

    入门知识: 一.关于作用域: 对于变量的作用域,执行声明并在内存中存在,该变量就可以在下面的代码中使用. if 10 == 10: name = 'allen' print name 以下结论对吗? ...

  7. Python之路(第九篇)Python文件操作

    一.文件的操作 文件句柄 = open('文件路径+文件名', '模式') 例子 f = open("test.txt","r",encoding = “utf ...

  8. Python之路(第二篇):Python基本数据类型字符串(一)

    一.基础 1.编码 UTF-8:中文占3个字节 GBK:中文占2个字节 Unicode.UTF-8.GBK三者关系 ascii码是只能表示英文字符,用8个字节表示英文,unicode是统一码,世界通用 ...

  9. Python之路(第一篇):Python简介和基础

    一.开发简介 1.开发:      开发语言:               高级语言:python.JAVA.PHP.C#..ruby.Go-->字节码                低级语言: ...

随机推荐

  1. ES使用小结之索引Rollover

    Elasticsearch 使用小结之索引Rollover 索引名 一般而言,客户端将数据每天写入一个索引,比如直接写入YYYY-MM-HH格式的索引,那么我们只需要在写入的客户端里面获取时间,然后得 ...

  2. QT 线程的使用(继承QThread)

    对于多线程而言,要注意资源的同步和互斥问题,但对于单独的一个线程,则只需要对它的run方法进行重写. 下面实现了一个简单的线程 widget.h文件 #ifndef WIDGET_H #define ...

  3. python学习-7 条件语句 while循环 + 练习题

    1.死循环 while 1 == 1: print('ok') 结果是一直循环 2.循环 count = 0 while count < 10: print(count) count = cou ...

  4. Java手写简单Linkedlist一(包括增加,插入,查找,toString,remove功能)

    @Java300 学习总结 一.自定义节点 LinkList底层为双向链表.特点为查询效率低,但增删效率高,线程不安全. 链表数据储存在节点,且每个节点有指向上个和下个节点的指针. 创建ggLinke ...

  5. js 超浓缩 双向绑定

    绑定确实是个有趣的话题. 现在我的绑定器有了不少的功能 1. 附着在Object对象上,一切以对象为中心 2. 与页面元素进行双向绑定 3. 与任意对象绑定,主要是应用在绑定到页面元素的一些属性上,比 ...

  6. OPENGL 显示BMP图片+旋转

    VS2010/Windows 7/ 1. 需包含头文件 stdio.h, glaux.h, glut.h.需要对应的lib,并添加包含路径 2. 窗口显示用glut库的函数 3. bmp图片从本地读取 ...

  7. 系统性能分析-vmstat命令详解

    最近温馨巩固Linux 操作系统的 vmstat命令,这个命令所能打印的系统信息满多的,比较好用,就顺当记录下重要的点,方便以后排查系统问题时拿出来用 字段 含义 procs 进程信息字段: -r:正 ...

  8. 复选框已经有checked,但是页面没有选中效果(解决)

    原代码: $("#checked").click(function(){ $(".input[name="checked"]").attr( ...

  9. SQL优化的总结和一些避免全盘扫描的注意事项

    1.应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描. 2.应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一 ...

  10. eclipse debug 调试找不到资源问题解决

    eclipse debug 的时候,如果使用maven bulid,就可能找不到class,这种情况就需要先停止服务,然后配置 Run configurations-Source,然后remove掉D ...