zoukankan      html  css  js  c++  java
  • 【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()
    View Code

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

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

    <div style=" 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=" 245px;" >
                <img src="/%s" alt="" style=" 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=" 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=" 245px;" >
                <img src="/%s" alt="" style=" 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=" 245px;float: left">
                {% for item in queryset_dict %}
                    {% image_show item forloop.counter 4 1 %}
                {% endfor %}
            </div>
            <div style=" 245px;float: left">
                {% for item in queryset_dict %}
                    {% image_show item forloop.counter 4 2 %}
                {% endfor %}
            </div>
            <div style=" 245px;float: left">
                {% for item in queryset_dict %}
                    {% image_show item forloop.counter 4 3 %}
                {% endfor %}
            </div>
            <div style=" 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=" 245px;float: left">
        {% for item in queryset_dict %}
            {% if filter模版语言返回结果 %}
             <div style=" 245px;" >
                <img src="/{{ item.student__pic }}" alt="" style=" 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=" 245px;float: left">
        {% for item in queryset_dict %}
            {% if forloop.counter|image_show2:"4,0" %}
             <div style=" 245px;" >
                <img src="/{{ item.student__pic }}" alt="" style=" 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=" 245px;float: left">
    
            </div>
            <div style=" 245px;float: left">
    
            </div>
            <div style=" 245px;float: left">
    
            </div>
            <div style=" 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>
    前端页面
  • 相关阅读:
    IDEA中快速排除maven依赖
    Maven构建war项目添加版本号
    运行shell脚本报/bin/bash^M: bad interpreter错误排查方法
    Shell杀tomcat进程
    根据URL下载文件
    关闭Centos的自动更新
    CentOS下建立本地YUM源并自动更新
    为Linux服务器伪装上Windows系统假象
    ServerInfo.INI解密
    请教给终端推销域名的邮件该怎么写?
  • 原文地址:https://www.cnblogs.com/5poi/p/6723747.html
Copyright © 2011-2022 走看看