作者: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 方法
__init__
- 不需要传参数
- 服务器响应第一个请求的时候自动调用
- 用于确定是否启用该中间件
process_request(self, request)
- 在执行视图之前被调用(分配url匹配视图之前),每个请求都会调用,返回None或者HttpResponse对象
process_view(self, request, view_func. view_args, view_kwargs)
- view_func:视图函数
- view_args:视图函数的参数,按个接受
- view_kwargs:视图函数的参数,按字典接受
- 调用视图之前执行,每个请求都会调用,返回None或者HttpResponse对象
process_template_response(self, request, response)
- 在视图刚好执行完后调用,每个请求都会调用,返回None或者HttpResponse对象
- 使用render
process_response(self, request, response)
- 所有响应返回浏览器之前调用,每个请求都会调用,返回HttpResponse对象
process_exception(self, request, exception)
- 当视图抛出异常时调用,返回HttpResponse对象
2.2 方法的调用过程示意图
2.3 自定义中间件
- 在工程目录下的middleware目录下创建myApp
- 创建一个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 分页
- 两个对象:
Paginator
和Page
4.1 Paginator对象
4.1.1 创建对象
- 格式:
Paginator(列表,整数)
- 返回值:返回一个分页对象
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的关系
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_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模型
- 点击增加可以进行相关的操作
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 问题
- 用户发起request,并且要等待response返回,但在视图中有一些耗时的操作,导致用户可能会等待很长时间才能接收response,这样用户体验很差(登录/注册操作)
- 网站每隔一段时间要同步一次数据,但是http请求是需要触发的(实时更新数据的网页)
7.2 解决
使用Celery
- 将耗时的操作放在celery中执行
- 使用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
- 在
INSTALLED_APPS
中添加'djcelery'
- 在最后添加
# 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', )
然后视频就没了。