【Python之路】特別篇--Django瀑布流實現

 

瀑布流

  瀑布流,又稱瀑布流式佈局。是比較流行的一種網站頁面佈局,視覺表現爲良莠不齊的多欄佈局,隨着頁面滾動條向下滾動,這種佈局還會不斷加載數據塊並附加至當前尾部。最先採用此佈局的網站是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()
View Code

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})
View Code

4.前端使用模板語言 for循環獲得每個item數據ide

<div style="width: 245px;float: left">
    {% for item in queryset_dict %}
        ....
    {% endfor %}
</div>
View Code

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')
View Code

注意: 後臺獲取的數據形式爲 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')
    }
})
View Code

完整代碼:

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>
前端頁面
相關文章
相關標籤/搜索