需求分析

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

  • 以瀑布流形式布局,从数据库中取出图片
  • 每次取出等量(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 之瀑布流实现的更多相关文章

  1. Django实现瀑布流,组合搜索

    Django中组合搜索功能 需求分析 很多电商网站中有组合搜索的功能,所谓组合搜索就是网页中组合多个条件,对数据库中进行查询,并且将结果显示在页面中,看个例子吧: 注意红框中的标识,我们可以根据URL ...

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

    django实现图片瀑布流布局 我们在一些图片网站上经常会看到,满屏都是图片,而且图片都大小不一,却可以按空间排列.默认一个div是占用一行,当想把div里的图片并排显示的时候,只能使用float属性 ...

  3. Django之瀑布流

    一. 小功能瀑布流的实现 1.完成效果图 2.代码部分 <1>models.py from django.db import models # Create your models her ...

  4. JavaScript中作用域回顾(避免使用全局变量)(瀑布流的实现)(scroll事件)以及Django自定义模板函数回顾

    页面显示照片样式为瀑布流: 上面的div个数可以按照自己安排进行划分.img的分布可以使用模板标签以及自定义模板函数进行排布: 自定义模板函数实现可以看,最后几列:python---django中模板 ...

  5. Django模板语言中的自定义方法filter过滤器实现web网页的瀑布流

    模板语言自定义方法介绍 自定义方法注意事项 Django中有simple_tag 和 filter 两种自定义方法,之前也提到过,需要注意的是 扩展目录名称必须是templatetags templa ...

  6. 【Python之路】特别篇--Django瀑布流实现

    瀑布流 瀑布流,又称瀑布流式布局.是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部.最早采用此布局的网站是Pinteres ...

  7. 轮播组件/瀑布流/组合搜索/KindEditor插件

    一.企业官网 ### 瀑布流 ​ Models.Student.objects.all() #获取所有学员信息 ​ 通过div进行循环图片和字幕 ​ 1.以template模板方法实现瀑布流以列为单位 ...

  8. jquery瀑布流的制作

    首先,还是来看一下炫酷的页面: 今天就边做边说了: 一.准备工作 新建css,js,img文件夹存放相应文件,并在demo.html文件中引入外部文件(注意要把jquery文件引入),这里就不过多描述 ...

  9. js瀑布流 原理实现揭秘 javascript 原生实现

    web,js瀑布流揭秘 瀑布流再很久之前流行,可能如我一样入行晚的 ,可能就没有机会去使用.但是这个技术终究是个挺炫酷的东西,花了一个上午来研究,用原生js实现了一个,下面会附上源码,供大家解读. 说 ...

随机推荐

  1. 回溯法 | 旅行商问题(TSP问题)

    学习链接: 回溯法解旅行商问题(TSP).贪心算法:旅行商问题(TSP) 今天早上做了无数个梦,然后被紧紧地吸附在床上.挣扎一番后爬起来,已经是9点了.然后我开始研究旅行商问题. 在一个无向图中找到一 ...

  2. [HNOI2015]亚瑟王(概率期望,DP)

    题目大意:很清晰了,不写了. $1\le T\le 444,1\le n\le 220,0\le r\le 132,0<p_i<1,0\le d_i\le 1000$. $p_i$ 和 $ ...

  3. Kdtree原理以及 vs Octree

    1. Kdtree原理 Kdtree是一种划分k维数据空间的数据结构,本质也是一颗二叉树,只不过每个节点的数据都是k维,当k=1时,就是图1所示的普通二叉树. 图1 1)Kdtree的建立 建立Kdt ...

  4. [C++进阶] 数据结构与算法

    1 出栈&入栈问题 一个栈的入栈序列为ABCDE,则不可能的出栈序列为?(不定项选择题) A:ECDBA  B:DCEAB   C:DECBA   D:ABCDE   E:EDCBA 正确答案 ...

  5. Storm里面fieldsGrouping和Field参数和 declareOutputFields

    Fields,个人理解,类似于一张表,你取那些字段以及这些字段所对应的数据给后面的bolt用 这个Field通常和fieldsGrouping分组机制一起使用,这个Field特别难理解,我自己也是在网 ...

  6. C语言字节对齐分析

    1.前言 什么是字节对齐呢?现代计算机中的内存空间都是按字节(byte)划分的,从理论上讲似乎任何类型的变量的访问都可以从任何地址开始,但是实际情况是在访问特定变量的时候经常需要在特定的内存地址进行访 ...

  7. 全国自考C++程序设计

    一.单项选择题(本大题共20小题,每小题1分,共20分)在每小题列出的四个备选项中 只有一个是符合题目要求的,请将其代码填写在题后的括号内.错选.多选或未选均无 分. 1. 编写C++程序一般需经过的 ...

  8. 构造 + 离散数学、重言式 - POJ 3295 Tautology

    Tautology Description WFF 'N PROOF is a logic game played with dice. Each die has six faces represen ...

  9. 不一样的LCA——luoguP1852跳跳棋

    洛谷端题目链接 loj端题目链接 题目大意: 在一条数轴上进行跳跳棋游戏.棋子只能摆在整点上.每个点不能摆超过一个棋子.用跳跳棋完成:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动 ...

  10. DEV 总结

    转自:https://www.cnblogs.com/yuerdongni/archive/2012/09/08/2676753.html 1. 如何解决单击记录整行选中的问题 View->Op ...