备战秋招——记录自己学习的第四天(Django项目难点拆分——分页及点赞效果示例)

一、利用前后端交互实现分页功能

我们知道,使用django时,如果想让数据库中的信息在前端页面显示时,所有信息会全部展示出来,这显然与我们生活中所见到的app不符。为了达到将数据库中的数据进行分批次显示这一需求,便要我们对后端的数据进行处理,每次取出固定的条数。
假设以班级管理为例,我们要拿到班级信息,我们先配置好django的环境:

第一步:设置好url

from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('classes.html/', views.handle_classes),
    ]

第二步,创建班级数据库:

from django.db import models
class Classes(models.Model):
    caption = models.CharField(max_length=32)

第三步,事先导入jquery数据包,将其存放在主目录新建的static文件夹中(前端实现需要用到jquery知识):
在这里插入图片描述
第四步:由于django2.2版本在创建app的时候,会自动在INSTALLED_APPS中添加app的名称,因此无需再次添加app的名字。项目中需要利用form表单提交,预先将MIDDLEWARE中的csrf注释掉,配置setting文件夹:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

STATIC_URL = '/static/'
STATICFILES_DIRS=(
    os.path.join(BASE_DIR,"static"),
)

准备工作已经全部完成,下面在终端输入命令,在数据库中创建班级列表,并启动服务端:

第一步:python manage.py makemigrations
第二步:python manage.py migrate

第三步(启动服务端):python manage.py runserver 8080(端口号随意)

为了使大家更好的理解前后端的交互,我先将其他代码删掉,只留下分页所需的前后端交互,下面是在body中插入的前端代码:

    <div class="pagination">
        {{ str_pager }}
    </div>

因为分页是几乎所有前后端项目中都必备的需求,我们将将其功能封装为模块,放入主目录下新建的utils文件夹下:
在这里插入图片描述
下面先附上分页代码:

class PagerHelper:
    def __init__(self,total_count,current_page,base_url,per_page=10):
        self.total_count = total_count #封装总共多少条信息
        self.current_page = current_page #封装当前页面,以当前页面为基础(假设为n页),显示总页面的n-m~~n+m页
        self.base_url = base_url #封装需要分页的url
        self.per_page = per_page  #封装每页中显示的数据量

    @property
    def db_start(self):
        return (self.current_page -1) * self.per_page  # 设置显示到页面中的起始数据的编号

    @property
    def db_end(self):
        return self.current_page * self.per_page   # 设置显示到页面中的结尾数据的编号

    def total_page(self):
        v, a = divmod(self.total_count, self.per_page)  #divmod() 函数把除数和余数运算结果结合起来
        if a != 0:
            v += 1
        return v

    def pager_str(self):

        v = self.total_page()

        pager_list = []
        if self.current_page == 1:  #如果当前页面为1,那么不能再往前去取
            pager_list.append('<a href="javascript:void(0);">上一页</a>')
        else:
            pager_list.append('<a href="%s?p=%s">上一页</a>' % (self.base_url, self.current_page - 1,))

        # 6,1:12
        # 7,2:13
        if v <= 11:  # 每次显示前后5页,那么如果总页面小于11,则第一页固定为1
            pager_range_start = 1
            pager_range_end = v
        else:
            if self.current_page < 6:
                pager_range_start = 1
                pager_range_end = 11 + 1
            else:
                pager_range_start = self.current_page - 5
                pager_range_end = self.current_page + 5 + 1
                if pager_range_end > v:
                    pager_range_start = v - 10
                    pager_range_end = v + 1

        for i in range(pager_range_start, pager_range_end):
            if i == self.current_page:
                pager_list.append('<a class="active" href="%s?p=%s">%s</a>' % (self.base_url, i, i,))
            else:
                pager_list.append('<a href="%s?p=%s">%s</a>' % (self.base_url, i, i,))

        if self.current_page == v:
            pager_list.append('<a href="javascript:void(0);">下一页</a>')
        else:
            pager_list.append('<a href="%s?p=%s">下一页</a>' % (self.base_url, self.current_page + 1,))

        pager = "".join(pager_list)  #将列表中的字符串,进行切割变成一个个的<a>标签
        return pager

这里,有一个点有些小伙伴可能不太清除,那就是装饰器的作用:@property
可以参考这篇文章:装饰器的解释
这里我简单的可以将其概括为:将get/set方法变成属性赋值,可以直接进行调用

再附上后端代码:

from django.shortcuts import render,redirect,HttpResponse
from app01 import models
from django.utils.safestring import mark_safe
from django import views
import json


def handle_classes(request):
    if request.method == "GET":

        # 获取所有的班级列表
        # models.Classes.objects.create(caption='全栈一班')
        # models.Classes.objects.create(caption='全栈二班')
        # models.Classes.objects.create(caption='全栈三班')


        current_page=request.GET.get('p',1)
        current_page=int(current_page)

        total_count = models.Classes.objects.all().count()

        from utils.page import PagerHelper

        obj=PagerHelper(total_count,current_page,'/classes.html',10)  #创建分页对象
        pager = obj.pager_str()

        cls_list = models.Classes.objects.all()[obj.db_start:obj.db_end]
        current_user = request.session.get('username')
        return render(request,
                      'classes.html',
                      {'username': current_user, 'cls_list': cls_list,'str_pager':mark_safe(pager)})

    elif request.method == "POST":
        # Form表单提交的处理方式
        # Ajax
        import json

        response_dict = {'status': True, 'error': None, 'data': None}

        return HttpResponse(json.dumps(response_dict))

大家查看一下效果图:
在这里插入图片描述

二、利用最基础的CSS、JS、jQuery知识,实现点赞效果

点击够,赞的效果会发生变化,这里我们不作考虑。难点的地方在于怎么能有一个+1渐渐的浮现出来先附上效果图:
在这里插入图片描述

上述配置jQuery已经讲过,这里不再赘述,先配置urls和views:

from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('test.html/', views.test),
]
def test(request):
    return render(request,"test.html")

下面是前端页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <style>

        .item{
            height: 100px;
            border: solid 1px deepskyblue;
        }
        
        .zan{
            height: 30px;
            width: 30px;
            background-color: darkgray;
            color: white;
            margin-top: 35px;  // 让文字赞居中
            cursor: pointer;
            position: relative;

        }
        .zan span{
            position: absolute;   //将创建的+1 在文字赞的旁边显示
        }



    </style>


</head>
<body>

    <div class="item">
        <div class="zan">赞</div>
    </div>

</body>

<script src="/static/jquery-3.3.1.js"></script>

<script>
    $(function () {
        $('.zan').click(function () { // 绑定点击事件
            var fz = 12;
            var tp = 5;
            var lp = 5;
            var op = 1;
            var tag = document.createElement('span'); //当点击赞的时候,创建span标签,内容显示为‘+1’
            tag.innerHTML = "+1";
            tag.style.color = "red";
            tag.style.fontSize = fz + 'px';
            tag.style.top = tp + 'px';
            tag.style.left = lp + 'px';
            tag.opacity = op;
            $(this).append(tag);//当前的标签下,添加tag标签

            var obj = setInterval(function () {  //需求的关键处,设置一个定时器
                fz += 5;
                tp -= 5;
                lp += 5;
                op -= 0.2;

                tag.style.fontSize = fz + 'px';
                tag.style.top = tp + 'px';
                tag.style.left = lp + 'px';
                tag.opacity = op;   //将透明度逐渐变低
                if (op <0){  //当透明度变为0的时候,删除定时器和tag标签
                    clearInterval(obj);
                    $(tag).remove();
                }
            },100)//每100毫秒执行一次
        })
    })

</script>
</html>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值