作者: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://:[email protected]: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', )
然後視頻就沒了。