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://:[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', )

然後視頻就沒了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章