Python—Django中的高级应用

作者:BerenCamlost

1 静态文件

1.1 文件目录

文件目录

1.2 概述

  • 包括CSS、js、json、图片文件、字体文件等

1.3 配置settings.py文件

STATIC_URL = '/static/'
# 普通文件
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]
  • STATIC_URL配置的是可以用链接的文件,如图片等
  • STATICFILES_DIRS配置的是普通的文件,如css、js文件等
  • 一般情况下,这两个都命名为static

1.4 HTML

{% load static from staticfiles %}
{#引入static标签,表示路径#}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
{#    <link rel="stylesheet" type="text/css" href="/static/sunck/css/style.css"/>#}
    <link rel="stylesheet" type="text/css" href="{% static 'sunck/css/style.css' %}"/>
</head>
<body>
    <h1>You are successful!</h1>
    <img src="{% static 'sunck/img/VerificationCode.png' %}" alt="验证码">
    <hr>
    <img src="{% static 'sunck/img/1.jpg' %}" alt="杨幂">
    <hr>
</body>
</html>

2 中间件

  • 一个轻量级,底层的插件,可以介入Django的请求和响应。
  • 一个Python类

2.1 方法

  1. __init__
    • 不需要传参数
    • 服务器响应第一个请求的时候自动调用
    • 用于确定是否启用该中间件
  2. process_request(self, request)
    • 在执行视图之前被调用(分配url匹配视图之前),每个请求都会调用,返回None或者HttpResponse对象
  3. process_view(self, request, view_func. view_args, view_kwargs)
    • view_func:视图函数
    • view_args:视图函数的参数,按个接受
    • view_kwargs:视图函数的参数,按字典接受
    • 调用视图之前执行,每个请求都会调用,返回None或者HttpResponse对象
  4. process_template_response(self, request, response)
    • 在视图刚好执行完后调用,每个请求都会调用,返回None或者HttpResponse对象
    • 使用render
  5. process_response(self, request, response)
    • 所有响应返回浏览器之前调用,每个请求都会调用,返回HttpResponse对象
  6. process_exception(self, request, exception)
    • 当视图抛出异常时调用,返回HttpResponse对象

2.2 方法的调用过程示意图

流程图

2.3 自定义中间件

  1. 在工程目录下的middleware目录下创建myApp
  2. 创建一个python文件
  • 【注意】在2.7之后的python必须包含middlewareMixin
from django.utils.deprecation import middlewareMixin
class MyMiddle(middlewareMixin):
    def process_request(self, request):
        print("get参数为: ", request.GET.get("a"))

2.4 使用自定义的中间件

  • 配置settings.py文件
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',
    'middleware.sunck.myMiddle.MyMiddle'  # 添加这一句
]

3 上传

3.1 概述

  • 文件上传时,文件数据request.FILES属性中
  • 【注意】:form表单要上传文件需要加enctype="multipart/form-data",即:
<form method="post" action="{% url 'sunck:save_file' %}" enctype="multipart/form-data">
    {% csrf_token %}
	  <input name="file" type="file" style="position: fixed; top: 21px; left: 43%; right: 50%; bottom: auto;"/>
  <input type="submit" value="提交" style="position: fixed; left: 43%; right: 50%; bottom: auto; top: 51px;"/>
  </form>
  • 【注意】:上传文件必须用post请求

3.2 上传路径

  • static目录下创建一个新的目录upfile用于存储上传的文件
    在这里插入图片描述
  • 配置settings.py文件 MDEIA_ROOT = os.path.join(BASE_DIR, r'static\upfile')
# 文件上传目录
MEDIA_ROOT = os.path.join(BASE_DIR, r'static\upfile')

3.3 代码示例

3.3.1 urls

    path('advance/upfile/', views.up_file, ),
    path('advance/savefile/', views.save_file, name='save_file'),

3.3.2 views

# Django高级应用-上传文件
def up_file(request):
    return render(request, 'sunck/advanced/upfile.html')


import os  # 文件的复制
from django.conf import settings  # 引入setting.py文件
def save_file(request):
    if request.method == "POST":  # 检查request的方式是不是post(必须为post)
        f = request.FILES['file']  # 取文件
        file_path = os.path.join(settings.MEDIA_ROOT, f.name)  # 取文件地址
        with open(file_path, 'wb') as fp:  # 保存文件
            for info in f.chunks():  # 分批次读写
                fp.write(info)
        return HttpResponse('<h1>保存成功!终于成功了!!!</h1>')
    else:
        return HttpResponse('文件上传失败')

3.3.3 upfile.HTML

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>upfile</title>
<style type="text/css">
</style>
</head>

<body>
<form method="post" action="{% url 'sunck:save_file' %}" enctype="multipart/form-data">
    {% csrf_token %}
	  <input name="file" type="file" style="position: fixed; top: 21px; left: 43%; right: 50%; bottom: auto;"/>
  <input type="submit" value="提交" style="position: fixed; left: 43%; right: 50%; bottom: auto; top: 51px;"/>
  </form>
</body>
</html>

4 分页

  • 两个对象:PaginatorPage

4.1 Paginator对象

4.1.1 创建对象

  1. 格式:Paginator(列表,整数)
  2. 返回值:返回一个分页对象

4.1.2 属性

count  # 对象总数
num_pages  # 页面总数
page_range  # 页码列表
	# 例如:
    [1,2,3,4,5]
    # 页码从1开始

4.1.3 方法

  • page(num)
    获得一个Page对象,如果提供的页码不存在会抛出"InvalidPage"异常

4.1.4 异常

  • InvalidPage:当向 page()传递的是一个无效的页码时抛出
  • PageNotAnInteger:当向 page()传递的不是一个整数时抛出
  • EmptyPage:当向 page()传递一个有效值,但是该页面里没有数据时抛出

4.2 Page对象

4.2.1 创建对象

  • Paginator对象的 page()方法返回得到Page对象
  • 不需要手动创建

4.2.2 属性

object_list  # 当前页上所有数据(对象)列表
number  # 当前页的页码值
paginator  # 当前page对象关联的paginator对象

4.2.3 方法

has_next() 				判断是否有下一页,如果有返回 True
has_previous() 			判断是否有上一页,如果有返回 True
has_other_pages() 		判断是否有上一页或者下一页,如果有返回 True
next_page_number() 		返回下一页的页码,如果下一页不存在抛出InvalidPage异常
previous_page_number() 	返回上一页的页码,如果上一页不存在,抛出InvalidPage异常
len() 					返回当前页的数据(对象)个数

4.3 Paginator和Page的关系

Paginator和Page的关系

4.4 代码示例

4.4.1 urls:

    path('advance/studentPages/', views.student_page, name='studentPages'),

4.4.2 views

# Django高级应用-分页
from django.core.paginator import Paginator, Page
def student_page(request):
    page_id = request.GET.get('page')
    if page_id is None:
        page_id = 1
    all_student_list = Students.stuObj2.all()  # 所有学生列表
    paginator = Paginator(all_student_list, 6)
    page = paginator.page(page_id)
    return render(request, 'sunck/advanced/studentPage.html', {'student': page})

4.4.3 HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>学生分页显示</title>
</head>
<body>
{% csrf_token %}
    <table border="1">
        <tr>
            <th>姓名</th>
            <th>年龄</th>
            <th>简介</th>
            <th>班级</th>
        </tr>
        {% for stu in student %}
            <tr>
                <td>{{ stu.sname }}</td>
                <td>{{ stu.sage }}</td>
                <td>{{ stu.scontend }}</td>
                <td>{{ stu.sgrade }}</td>
            </tr>
        {% endfor %}
    </table>
    <form method="get" action="{% url 'sunck:studentPages' %}" >
        {% for page in student.paginator.page_range %}
            {% if page == student.number %}
                <input type="submit" value="{{ page }}" name="page" style="background-color: aqua;color: crimson"/>
            {% else %}
                <input type="submit" value="{{ page }}" name="page">
            {% endif %}
        {% endfor %}
    </form>

</body>
</html>

4.4.4 效果:

效果

5 ajax 略

6 富文本

  • 可以在站点中使用,也可以在自定义视图中使用

6.1 安装

pip install django-tinymce
  • 安装成功之后提示
C:\WINDOWS\system32>pip install django-tinymce
Collecting django-tinymce
  Downloading https://files.pythonhosted.org/packages/8c/6f/ccd37b4b67bd86ac11ace8126d39682facfdb12e2de51b5bfe7ec512e2da/django_tinymce-2.8.0-py2.py3-none-any.whl (4.1MB)
    100% |████████████████████████████████| 4.1MB 46kB/s
Installing collected packages: django-tinymce
Successfully installed django-tinymce-2.8.0

6.2 在站点中使用(admin)

6.2.1 配置settings.py文件

  • 在APPS中添加'tinymce'
    'tinymce
  • 在末尾添加
# 富文本
TINYMCE_DEFAULT_CONFIG = {
    'theme': 'advanced',
    'width': 600,
    'height': 400,
}

6.2.2 models

  • 创建一个新的模型类
# 富文本
from tinymce.models import HTMLField
class Text(models.Model):
    str = HTMLField()
  • 记得重新制作迁移文件,并重新进行迁移
D:\project\test1>py manage.py makemigrations
D:\project\test1>py manage.py migrate
  • 迁移成功后如下所示:
D:\project\test1>py manage.py makemigrations
Migrations for 'sunck':
  sunck\migrations\0002_auto_20190130_1908.py
    - Create model Text
    - Change managers on grades
    - Change managers on students

D:\project\test1>py manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, sunck
Running migrations:
  Applying sunck.0002_auto_20190130_1908... OK

6.2.3 admin.py文件

admin.site.register(Text)

6.2.4 效果

  • 打开admin界面如下,可以看到有新建的texts模型
    1
  • 点击增加可以进行相关的操作
    2

6.3 在自定义视图中使用

6.3.1 urls

    path('advance/tinymce/', views.tinymce),  # 富文本
    path('advance/tinymceshow/', views.tinymce_show),

6.3.2 views

# Django高级应用-富文本
def tinymce(request):
    return render(request, 'sunck/advanced/tinymce.html', )


def tinymce_show(request):
    file = request.POST.get('str')
    return HttpResponse(file)

6.3.3 html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>富文本</title>
    <script type="text/javascript" src="/static/tiny_mce/tiny_mce.js"></script>
    <script type="text/javascript">
        tinyMCE.init({
            'mode': 'textareas',
            'theme': 'advanced',
            'width': 800,
            'height': 600,
        })
    </script>
</head>
<body>
    <form method="post" action="../tinymceshow/">
        {% csrf_token %}
        <textarea name="str">
            hello
        </textarea>
        <input type="submit" value="提交"/>
    </form>
</body>
</html>
  • 关于HTML中script的几点说明:
    • <script type="text/javascript" src="/static/tiny_mce/tiny_mce.js"></script>这句话定义的js文件的地址在static文件夹中似乎并不存在,但是就这么写就可以了
    • 'mode': 'textareas',的意思是将<textarea>标签变成富文本标签

6.3.4 效果

  • 略,自己脑补吧哈哈哈哈哈哈哈或
  • 傻调?

7 Celery

7.1 问题

  1. 用户发起request,并且要等待response返回,但在视图中有一些耗时的操作,导致用户可能会等待很长时间才能接收response,这样用户体验很差(登录/注册操作)
  2. 网站每隔一段时间要同步一次数据,但是http请求是需要触发的(实时更新数据的网页)

7.2 解决

使用Celery

  1. 将耗时的操作放在celery中执行
  2. 使用celery定时执行

7.3 概述

  • 任务task
    本质是一个Python函数,将耗时的操作封装成一个函数
  • 队列queue
    将要执行的任务放在队列里
  • 工人worker
    负责执行队列中的任务
  • 代理broker
    负责调度,在部署环境中使用redis

7.4 安装

pip install celery
pip install celery-with-redis
pip install django-celery

7.5 配置settings

  1. INSTALLED_APPS中添加'djcelery'
    1
  2. 在最后添加
# Celery 配置
import djcelery
djcelery.setup_loader()  # 初始化
BROKER_URL = 'redis://:sunck@127.0.0.1:6379/0'  # 代理
CELERY_IMPORTS = ('sunck.task')  # 任务文件路径

7.6 在应用目录下创建task.py文件

7.7 迁移生成celery需要的数据库表:

> python manage.py migrate

7.8 在工程目录下的project目录下创建celery.py文件

from __future__ import absolute_import

import os
from celery import Celery
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'whthas_home.settings')

app = Celery('portal')

app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


@app.task(bind=True)
def debug_task(self):
    print('request: {0!r}'.format(self.request))

7.9 urls

path('advance/celery/', views.celery),  # celery

7.10 views

# Django高级应用-Celery
def celery(request):
    return render(request, 'sunck/advanced/celery.html', )

然后视频就没了。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值