小言_互联网的博客

Django --图片瀑布流布局+动态的渲染

299人阅读  评论(0)

1. 瀑布流布局原理

在前端页面布局中,图片放置时存在图片宽度、长度大小不一的情况,在不调整图片大小成一致的情况下,选择瀑布流布局是很好的解决图片能紧致放置的一种办法。瀑布流如何解决这个问题呢?

  1. 设置页面div宽度为固定宽度;
  2. 将页面根据图片排列多少列分成相应的div个数,同时设置div的宽度为固定宽度,可以一样,也可以设置为不同。
  3. 从后台数据库中拿到图片链接,然后图片的索引下标求余图片列数(index%col)然后将图片对应放入相应的div中。
  4. 然后监听鼠标滚轮移动到屏幕最下端通过ajax自动加载图片,从而实现图片自动加载和瀑布流布局。

2 具体实现过程

2.1 图片数据库创建

创建一个表用来存放图片的链接,标题,简介。(后续通过scrapy爬取图片信息自动存入数据库中)

# 创建图片表
class Img(models.Model):
    src = models.CharField(max_length=256, verbose_name="图片链接") 	# 图片链接
    title = models.CharField(max_length=32, verbose_name="图片标题")	# 图片标题
    intro = models.CharField(max_length=32, verbose_name="简介")		# 图片简介
    add_time = models.DateTimeField(verbose_name="添加时间", auto_now_add=True)

    #def __str__(self):
        #return self.title   

2.2 视图函数

通过模板中传入的ajax数据请求进行处理然后传入到模板中进行渲染。

# 导入模块
from django.shortcuts import render, redirect
from django.http import HttpResponse
from pbl.models import Img
import json

# 图片显示
def index(request):
    img_obj_list = Img.objects.all()
    return render(request, "pbl/index.html", context={"img_obj_list": img_obj_list})

#添加图片信息
def add_img(request):
    if request.method == "GET":
        return render(request, 'pbl/add_img.html')
    else: 
        src = request.POST.get("src")
        title = request.POST.get("title")
        intro = request.POST.get("intro")
        Img.objects.create(src=src, title=title, intro=intro)
        return redirect('pbl:index')

# 处理前端ajax请求
def get_img_ajax(request):
    nid = request.GET.get('nid')  # 拿到前端每次传过来的最后一张图片的id
    img_query = Img.objects.filter(id__gt=nid).values('id', "src") # 拿到图片id大于nid的所有图片的id和src
    img_list = list(img_query )  # 对拿到的query对象进行列表处理
    # 将数据放入到字典中传入到前端
    res = {   
        'data': img_list  # img_list中的数据样式[{'id': 23, 'src': '/static/pbl/img/1.jpg', 'title': '23'}]
    }
    return HttpResponse(json.dumps(res))

2.3 模板中

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>瀑布流</title>
    <style type="text/css">
    	# 对最外层的div设置固定宽度和居中
        .box{  
            width:1000px;
            margin: 30px auto;
        }
        # 对图片对应的div设置固定宽度左浮动
        .box .item{
            width:25%;
            float:left;
        }
        # 对图片设置固定宽度大小
        .box .item img{
            width:100%;
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>

    </div>
    <script src="{% static 'jQuery_3.3.1.js' %}"></script>
    <script>
    	'''
    	这里将所有方法封装进类中进行操作,防止将变量放在外面成全局变量影响其他功能的使用,同时类里面
    	initImg()方法来处理图片如何放置;scollEvent()用来监听滚动条滑动事件(其中涉及到如何判定右
    	边滚动条滑动到最低端:当文档高度 = 窗口高度和滚动条高度时滚动条滑动到最低端),如果有时滚动条
    	滑动到最底端后:文档高度 != 窗口高度和滚动条高度时,有可能是页面进行缩放或者是放大了。
    	'''
    	# 页面运行时执行initImg()和scollEvent()方法
        $(function () {
            var obj = new scrollImg();  # 实例化对象
            obj.initImg();				# 对象调用initImg方法
            obj.scrollEvent();			# 对象调用scrollEvent方法
        });
        
		# 构造scrollImg类
        function scrollImg(){
            this.nid = 0;  # 初始化nid的值,图片id
            this.lastPosition = 3;  # 初始化lastPosition 的值,每次最后一张图片的位置
            
            # 构造处理图片放置方法并发送ajax请求
            this.initImg = function () {
           		#这里的this就是实例化对象obj
                var my_this = this; # 由于不知道ajax中使用什么函数发送请求,因此外面先定义一个参数来接收当前的obj
                $.ajax({
                    url:"{% url "pbl:get_img_ajax" %}",
                    method:"get",
                    dataType:"JSON",
                    data:{'nid':my_this.nid}, # 传入最后一张图片的id这样从数据库中再次取数据时避免取到重复值
                    success:function (arg) {
                        var img_list = arg.data;	# arg中的数据样式 {'data': [{'id': 23, 'src': '/static/pbl/img/1.jpg', 'title': '23'}]}.....
                        # each循环img_list拿到列表中的索引index和里面包含字典内容
                        $.each(img_list,function (index,dataDict) {
                            var rem = (index+my_this.lastPosition+1) % 4;  # 求余 获取数据放在哪个div里面,这里lastPosition初始值为3可以避免初始位置在放置图片时不是从0开始放的。
                            var tag = document.createElement('img');  #在图片div中创建img标签
                            tag.src = dataDict.src;  # 给img标签添加src属性值
                            $('.box').children().eq(rem).append(tag); # 最外层的div里面的图片div对应的下标值添加img属性值
                            # 当下标值+1等于列表长度时表示图片全部放完了
                            if(index+1 == img_list.length){
                                my_this.nid = dataDict.id;   # 每次获取最后图片的id 
                                my_this.lastPosition = rem;  # 获取到最后的位置,后面图片都接着位置进行放置 

                            }
                        })
                    }
                })
            };
			# 构造滚动条函数,用来监听滚动条事件
            this.scrollEvent = function () {
            	#这里的this就是实例化对象obj
                var that = this;
                # 监听滚动条事件
                $(window).scroll(function () {
                # 文档高度 = 窗口高度+滚动高度 时表示滚动条滑动到最下面了
                var docHeight = $(document).height(); # 文档高度 
                var winHeight = $(window).height(); # 窗口高度
                var scrollHeight = $(window).scrollTop(); # 滚动高度 
                if(winHeight + scrollHeight == docHeight){
                    that.initImg(); # 当每次滚动条滑动到最下面时再一次调用initImg()重新获取图片放置在页面
                }
                })
            }
        }
    </script>
</body>
</html>

这样就完成了瀑布流布局+ajax自动加载数据,渲染到页面。


转载:https://blog.csdn.net/hl120841/article/details/100851806
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场