Django瀑布流的实现示例

作者:风老魔 时间:2021-05-09 10:07:42 

需求分析

现在是 "图片为王"的时代,在浏览一些网站时,经常会看到类似于这种满屏都是图片。图片大小不一,却按空间排列,就这是瀑布流布局。

Django瀑布流的实现示例

  • 以瀑布流形式布局,从数据库中取出图片

  • 每次取出等量(7 条)的图片,加载到页面

  • 当滑轮滚动到最底端时,自动再加载图片

实现流程

  • 以包形式管理模型

  • 将图片自动上传到静态文件 static

  • 前端页面每行排列四张图片(四个 div )

  • 当页面加载时,以 ajax 形式自动向后台发送请求,获取图片数据,再用 js 循环生成 img 标签添加到每个 div 中

  • JS 循环图片信息列表,将当前循环元素的索引与每行排列的图片数目(4张)求余数,再利用余数定位每个 div 标签

模型设计

在这里,我以包的形式管理模型 models,编写 app/models/video/img_models.py

from django.db import models

class Img(models.Model):
   """
   upload_to: 上传文件地址
   """
   src = models.FileField(max_length=64, verbose_name='图片地址', upload_to='app/static/app/upload')
   title = models.CharField(max_length=64, verbose_name='标题')
   summary = models.CharField(max_length=128, verbose_name='简介')

class Meta:
       verbose_name_plural = '图片'

def __str__(self):
       return self.title

视图函数

编写 app/views.py

from django.shortcuts import render
from django.http import JsonResponse
from app.models.video.img_models import Img

def img(request):

return render(request, 'app/img.html')

def getImgs(request):
   nid = request.GET.get('nid')
   print(nid)

# nid 第一次取为 0,每次取 7 条
   last_position_id = int(nid) + 7
   postion_id = str(last_position_id)

# 获取 0 < id < 7 的数据
   img_list = Img.objects.filter(id__gt=nid, id__lt=postion_id).values('id', 'title', 'src')
   img_list = list(img_list)   # 将字典格式转换为列表形式
   ret = {
       'status': True,
       'data': img_list
   }

return JsonResponse(ret)

在后台取出符合条件的数据,然后打包成 JSON 格式数据,前端模板再通过 jQuery 将其循环生成 img 标签,并添加到 div 标签中。

模板

编写 app/templates/app/img.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>瀑布流</title>
   <style type="text/css">
       .box1{
           width: 1000px;
           margin: 0 auto;
       }

.box1 .item{
           width: 25%;
           float: left;
       }

.item img{
           width: 100%;
       }
   </style>
</head>
<body>
   <h1>瀑布流</h1>
   <div class="box1" id="container">
       <div class="item">

</div>

<div class="item">

</div>

<div class="item">

</div>

<div class="item">

</div>
   </div>

<script src="{% static 'app/jquery/jquery-3.1.1.js' %}"></script>
   <script>
       $(function () {
           initImg();
           scroll();
       });

NID = 0;
       LASTPOSTION = 3;    // 循环最后那个的位置
       function initImg() {
           $.ajax({
               url: '/app/getImgs/',
               type: 'GET',
               data: {nid: NID},
               dataType: 'JSON',
               success: function (arg) {
                   if (arg.status){
                      var img_list = arg.data;
                      $.each(img_list, function (index, value) {
                         var n = (index + LASTPOSTION + 1) % 4;
{#                          console.log(n);    // 0、1 、2 、3    一直为 0、1 、2 、3#}
                         var img = document.createElement('img');
                         img.src = '/' + value.src;    //  app/static/app/upload/7.jpg

// 也就是给第一、二、三、四给 div 添加 img 标签,eq(0) 为第一个
                         $('#container').children().eq(n).append(img);
                         if (index + 1 == img_list.length){
                             console.log(n, value.id);
                             LASTPOSTION = n;
{#                              NID = value.id;#}
                         }
                      });
                   }
               }
           })
       }

// 监听滑轮
       $(window).scroll(function () {
           // 文档高度
           var doc_height = $(document).height();
           // 窗口高度
           var window_height = $(window).height();
           // 滑轮高度
           var scroll_height = $(window).scrollTop();
           if (window_height + scroll_height == doc_height){
               initImg();
           }
       })

</script>
</body>
</html>

settings 配置

TEMPLATES = [
   {
       'BACKEND': 'django.template.backends.django.DjangoTemplates',

# templates 设置
       'DIRS': [os.path.join(BASE_DIR, 'templates')],
       'APP_DIRS': True,
       'OPTIONS': {
           'context_processors': [
               'django.template.context_processors.debug',
               'django.template.context_processors.request',
               'django.contrib.auth.context_processors.auth',
               'django.contrib.messages.context_processors.messages',
           ],
       },
   },
]

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

# 因为让模板能够找到 static 中图片,添加了 /app
STATIC_URL = '/app/static/'
STATICFILES_DIRS = (
   os.path.join(BASE_DIR, 'app', 'static'),
)

TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'app', 'templates'),)

urlconf 配置

这是我的 app/urls.py

# Project/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
   path('admin/', admin.site.urls),
   path('app/', include('app.urls')),
]

# app/urls.py
from django.urls import path
from app import views

urlpatterns = [
   path('img/', views.img, name='img'),
   path('getImgs/', views.getImgs, name='getImgs'),
]

包管理模型

整个项目的模型部分,以包的形式管理,有些功能部分单独设计模型文件,因此要在包文件中导入相应模型。

编写 app/models/video/__init__.py

from app.models.video.img_models import Img

使用对象封装全局变量

在上面 JS 代码中,我们使用了全局变量,实际开发中应该尽量避免使用全局变量,在这里用对象将其封装。

// 全局变量封装
$(function () {
   var obj = new ScrollImg();   // 定义一个对象
   obj.fetchImg();        
   obj.scrollEvent();
});

// 对象 ScrollImg
function ScrollImg() {
   // 将之前的全局变量封装在对象内部,仅其内部能使用
   this.NID = 0;      
   this.LASTPOSITION = 3;

// 向后台发送 ajax 请求,获取图片信息
   this.fetchImg = function () {
       var that = this;
       $.ajax({
           url: '/app/getImgs/',
           type: 'GET',
           data: {nid: that.NID},
           dataType: 'JSON',
           success: function (arg) {
               var img_list = arg.data;
               $.each(img_list, function (index, value) {
                   var n = (index + that.LASTPOSITION + 1) % 4;
                   var img = document.createElement('img');
                   img.src = '/' + value.src;

$('#container').children().eq(n).append(img);
                   if (index + 1 == img_list.length) {
                       that.LASTPOSITION = n;

// 每取完一次,便把最后那条的 id 赋值给 NID 传到后台,再根据这个条件取 7 条数据
                       that.NID = value.id;
                   }
               });
           }
       })
   };

this.scrollEvent = function () {
       var that = this;

// 监听滑轮,当滑轮高度+窗口高度==文档高度时,即表示滑轮已经滑动到最底部,再执行 fetchImg() 函数,再从数据库取出数据
       $(window).scroll(function () {
           var scroll_height = $(window).scrollTop();
           var window_height = $(window).height();
           var doc_height = $(document).height();
           if (scroll_height + window_height == doc_height ) {
               that.fetchImg();
           }
       })
   }
}

这是整个项目大致分布:

Django瀑布流的实现示例

参考博客

小功能瀑布流的实现

django实现瀑布流、组合搜索、阶梯评论、验证码

来源:https://blog.csdn.net/hj1993/article/details/129698688

标签:Django,瀑布流
0
投稿

猜你喜欢

  • Python解析nginx日志文件

    2023-09-07 18:22:09
  • 5 个简单实用的 CSS 属性

    2010-03-10 11:00:00
  • asp fso type属性取得文件类型代码

    2009-02-04 10:09:00
  • MySQL中truncate误操作后的数据恢复案例

    2024-01-12 20:45:56
  • js Event对象的5种坐标

    2024-04-22 22:31:32
  • PHP的mysqli_select_db()函数讲解

    2023-06-07 18:59:44
  • asp如何实现无组件上传二进制文件?

    2010-06-03 10:09:00
  • 对pandas replace函数的使用方法小结

    2022-07-04 15:20:24
  • Python 内存管理机制全面分析

    2021-07-17 07:21:17
  • Bootstrap风格的WPF样式

    2024-05-02 17:32:17
  • OverFlow:一个秘密武器

    2011-02-26 15:41:00
  • 利用anaconda保证64位和32位的python共存

    2021-07-23 09:18:24
  • 如何使用PHP中的字符串函数

    2024-05-11 10:01:52
  • python中filter,map,reduce的作用

    2023-12-18 11:13:15
  • JS动态添加与删除select中的Option对象(示例代码)

    2023-09-17 02:15:31
  • Go语言包管理模式示例分析

    2024-05-22 10:20:17
  • 详细介绍Python中的set集合

    2023-07-26 07:35:03
  • 浅谈python 中的 type(), dtype(), astype()的区别

    2022-09-13 22:40:39
  • MySQL单表查询操作实例详解【语法、约束、分组、聚合、过滤、排序等】

    2024-01-24 14:41:24
  • pytorch 预训练模型读取修改相关参数的填坑问题

    2021-11-07 01:08:36
  • asp之家 网络编程 m.aspxhome.com