瀑布流,又稱瀑布流式佈局。是比較流行的一種網站頁面佈局,視覺表現爲良莠不齊的多欄佈局,隨着頁面滾動條向下滾動,這種佈局還會不斷加載數據塊並附加至當前尾部。最先採用此佈局的網站是Pinterest,逐漸在國內流行開來。國內大多數清新站基本爲這類風格。html
實現效果:前端
數據存放方式:jquery
實現方式一: 自定義模版語言(simple_tag)ajax
思路: 後端獲取數據,,前端頁面使用自定義模板語言,實現第一條數據放第一個div,...,(經過求餘數實現),返回標籤字符串,頁面顯示.數據庫
實現方法:django
1.在app中建立templatetags模塊json
2.建立任意 .py 文件,如:newtag.py後端
from django import template from django.utils.safestring import mark_safe register = template.Library()
3.後臺獲取數據app
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數據ide
<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>