Django學習筆記


安裝django

  •   pip3 install django
    

刪除django

  •   pip3 uninstall django
    

創建django項目

  •   # django-admin startproject 創建的項目名
      django-admin startproject mywebsite
    

運行django項目

  •   # 運行時需要進入到django目錄
      python manage.py runserver
    

創建django-app(即django應用)

  •   # python manage.py startapp 應用名稱
      python manage.py startapp news
    

注冊django-app

  •   # 在項目下的settings文件中進行注冊
      # 在INSTALLED_APPS中增加需要注冊的應用名,如上news
    

修改django界面默認語言為中文

# 在項目下的settings文件中進行設置
# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans'

創建django后台管理員用戶與密碼

python manage.py createsuperuser

MVT

M——models

主要封裝數據庫,對數據庫進行訪問,對數據進行增刪改查。

V——views

進行業務邏輯處理

T——templates

主要進行展示

URL

url標准語法

protocol://hostname[:port]/path/[:parameters][?query]#fragment
  • protocol:協議,如http、https、ftp、mailto、ldap、file、news、telnet
  • hostname:ip地址
  • port:端口
  • path:路徑
  • parameters:參數
  • query:查詢
  • fragment:錨點

Path

path()標准語法

path(<route>, <view>, [name=None], [**kwargs])
  • route:表示路徑,從端口以后的URL地址,到/結束
  • view:表示route匹配成功后,需要調用的視圖,view必須是個函數,如果class必須使用as_view()轉換為函數
  • name:表示視圖的別名
  • **kwags:以字典形式傳遞的參數

路徑轉換器

path('AlexLu/Eva/<html>', views.web, name='web'),
# 其中<html>為傳遞給函數views.web的參數
  • str —— 用法:<str:html>匹配一個非空字符及,除去 ’/‘ ,默認使用的是這種方式
  • int —— <int:html>匹配0或正整數
  • slug —— <slug:html>由ASCII字母或數字組成,通過 ’-‘ 鏈接的字符串
  • uuid —— <uuid:html>uuid格式的字符串
  • path —— <path:html>匹配一個非空字符串,包括 ’/‘
path('index/<str:html>', views.index, name='index'),
path('index/<path:home>', views.home, name='home'),
path('page/<int:page>', views.page, name='page'),
path('index/<int:numa>/<int:numb>', views.sum, name='sum'),
path('slug/<slug:slugstr>', views.slugstr, name='slugstr'),
path('uuid/<uuid:uuid>', views.uuid, name='uuid'),

# ---------------------------------------------------------------------
def index(request, html):
    return HttpResponse(html)


def home(request, home):
    return HttpResponse('<h1>{}</h1>'.format(home))


def page(request, page):
    return HttpResponse('<h1>{}</h1>'.format(page))


def sum(request, numa, numb):
    return HttpResponse('<h1>{}</h1>'.format(numa+numb))


def slugstr(request, slugstr):
    return HttpResponse('<h1>{}</h1>'.format(slugstr))


def uuid(request, uuid):
    return HttpResponse('<h1 >{}</h1>'.format(uuid))

include

include的三種語法

1. module

  • include(module, namespace=None)

2. namespace

  • include(pattern_list)

3. pattern_list

  • include((pattern_list, app_namespace), namespace=None)

include用法說明

  • module —— 表示一個模塊(模型)文件
  • namespace —— 實例命名空間
  • pattern_list —— 必須是一個可迭代的path()或re_path()清單
  • app_namespace —— app命名空間

URL地址重定向

redirect(to, permanent=False, *args, **kwargs)
  • to —— 指需要重新定位的位置,這個位置可以是一個視圖,可以是一個url地址,也可以是一個模塊
  • permanent —— 默認為False,用來表示是否永久重定向

Reverse

reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)

HTTP

HttpResponse

HttpResponse(content, content_type=None, status=None, charset=None, reason=None *args, **kwargs)
  • content —— 返回給視圖函數的內容
  • content_type —— 返回給視圖函數的類型
    • text/html —— HTML文本字符串
    • text/plain —— 純文本
    • text/css
    • text/javascript
    • application/xml —— xml文本
    • application/json —— json文本
    • multipart/form-data —— 上傳文本
  • status —— Http響應代碼
    • 200 —— 表示成功
    • 404 —— 頁面找不到
  • charset —— 字符編碼設置

常見的幾種錯誤視圖代碼

  • 404 page not found
    • 找不到相應的頁面
  • 500 server error
    • 服務器錯誤
  • 400 bad request
    • 無效的請求
  • 403 HTTP forbidden
    • HTTP禁止訪問,權限不足
  • 200 OK
    • 請求成功

Http請求方式

  • 介紹 —— HTTP 協議定義一些方法,以指明為獲取客戶端(如您的瀏覽器或我們的 CheckUpDown 機器人)所指定的具體網址資源而需要在 Web 服務器上執行的動作。則這些方法如下:
    • OPTIONS( 選項 ) :查找適用於一個特定網址資源的通訊選擇。 在不需執行具體的涉及數據傳輸的動作情況下, 允許客戶端來確定與資源相關的選項以及 / 或者要求, 或是一個服務器的性能。
    • GET( 獲取 ) :檢索由網址資源所確定的信息,如獲取一個特定的網頁或圖片。這是最常用的方法。
    • HEAD( 頭 ) :除了服務器只反饋標頭信息而不是網址資源所確定的信息本身外, 基本同於 GET ( 獲取 ) 。 可用於獲取一個請求所要求的響應實體的元信息 ( metainformation) ,而不需傳輸響應實體本身。 經常用來測試超文本鏈接的有效性, 可達性, 和最近的修改。
    • POST( 投寄 ) :將數據提交到 Web 服務器,如 1 )在電子公告板,新聞組中,或向 郵件名單發送信息, 2 )提供輸入數據 - 通常由一個公共網關接口(CGI) 表, 到 一個數據處理進程, 3 )直接將記錄添加到一個數據庫中。
    • PUT( 放置 ) :將一個具體網址的數據設置( 置入 / 替換)成客戶提交的新數據。例如,將新的網頁上載給服務器。
    • DELETE( 刪除 ) :刪除與網址資源相關的數據。例如,刪除網頁。
    • TRACE( 跟蹤 ) :運行請求信息的一個遠程應用層回送。 實際上是一個 'ping', 用以測試 Web 服務器正在從客戶端接收什么數據。
    • CONNECT( 連接 ) :保留以便通過代理服務器和隧道一起使用(如 SSL )。這種方法只在 HTTP 1.1 版中定義, 而在先前的 1.0 版中卻沒有。

允許的HTTP請求方式——裝飾器

限定http請求方式

require_http_methods([Mthods_list])
  • Mthods_list為請求方式列表,如:[‘GET’, ‘POST’]

require_GET()

  • 只允許使用get方式進行請求

require_POST()

  • 只允許使用post方式進行請求

require_safe()

  • 只允許使用get方法和head方法的裝飾器

Render

  • 標准語法:

    render(<request>, <template_name>, context=None, content_type=None, status=None, using=None)
    
  • 必選參數

    • request —— 生成HttpRequest對象
    • template_name —— 指定需要渲染的模板名稱
  • 可選參數

    • context —— 上下文,必須是一個字典。在HTML文件中使用字典的Key,通過Key展示對應的value
    • content_type —— 指定上下文類型
    • status —— 響應狀態碼
    • using —— 用於加載模板的引擎名稱
      • Django templates language
      • jinjia2

過濾器

first

  • 返回列表list的第一個值

last

  • 返回列表list的最后一個值

length

  • 返回變量值的長度,可以用於字符串、列表

linebrakebr

  • 將純文本文件中的換行轉換為HTML中的換行符

linenumbers

  • 顯示行號

ljust

  • 左對齊

rjust

  • 右對齊

lower

  • 全部小寫

upper

  • 全部大寫

title

  • 將首字母全部大寫

wordcount

  • 統計單詞的數量

mysql

# 檢查是否安裝mysql
ps -aux | grep 'mysql'
# 安裝服務端
sudo apt-get install mysql-server
# 安裝客戶端
sudo apt-get install mysql-client

# 啟動服務
sudo service mysql start
# 停止服務
sudo service mysql stop
# 重啟服務
sudo service mysql restart

# 進入數據庫
sudo mysql -uroot -p
  • 取消mysql連接限制問題,否則每次進入數據庫都需要在前面加上sudo
# 進入管理員模式
alexlu@alexlu-Ubuntu:~$ sudo su
# 進入MySQL
root@alexlu-Ubuntu:/home/alexlu# mysql
# 查看用戶權限
mysql> select user,plugin from mysql.user;
# 更新root用戶密碼(此處密碼設為‘root’)
mysql> update mysql.user set authentication_string=PASSWORD('root'),plugin='mysql_native_password';
# 刷新設置
mysql> flush privileges;
# 退出MySQL與root用戶
mysql> exit;
root@alexlu-Ubuntu:/home/alexlu# exit
# 重啟數據庫服務
alexlu@alexlu-Ubuntu:~$ sudo service mysql restart
# 嘗試重新登陸(前面不加sudo)
alexlu@alexlu-Ubuntu:~$ mysql -uroot -proot

數據庫的創建與刪除

# 展示當前數據庫:
mysql> show databases;
# 創建數據庫(django為數據庫名稱)-此處未設置中文編碼
mysql> create database django;
# 查看創建的數據庫
mysql> show create database django;
# 刪除數據庫
mysql> drop database django;
# 創建支持中文編碼的數據庫
mysql> create database django charset='utf8';

表的創建與刪除

# 查看當前使用的數據庫
mysql> select database();
# 選擇使用的數據庫
mysql> use django_AlexLu;
# 創建表
mysql> create table students(
    -> id int primary key auto_increment not null,
    -> name varchar(20),
    -> age int default 20
    -> );
# 顯示創建的表
mysql> show create table students;
# 顯示表結構
mysql> desc students;
# 顯示已創建的表
mysql> show tables;
# 向表中插入數據
mysql> insert into students(name,age) values('Tom', 22);
# 查詢表中的數據
mysql> select * from students;

Django連接MySQL

  • 設置數據庫連接項
# 在django的settings.py文件中對DATABASES進行設置
DATABASES = {
    'default': {
        # 'ENGINE': 'django.db.backends.sqlite3',
        # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_AlexLu',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': 'localhost',
        'PORT': 3306
    }
}
  • 安裝pymysql
pip install pymysql
  • 配置pymysql
# 在django項目下的__init__.py中進行設置
import pymysql
pymysql.install_as_MySQLdb()
  • 可能會出現的錯誤
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.
  • 解決辦法
# 安裝libmysqlclient-dev
sudo apt-get install libmysqlclient-dev
# 安裝mysqlclient
pip install mysqlclient
# 修改django項目下的__init__.py(去掉上面第3步增加的兩行內容)改為:
import MySQLdb
  • 補充(mysql開發包的安裝)
# Ubuntu
sudo apt-get install libmysqlclient-dev
# CentOS
yum install python-devel mysql-devel

MySQL數據庫遷移

# 生成遷移文件
python manage.py makemigrations
# 將遷移文件映射到數據庫中
python manage.py migrate
# 如需強制遷移需要在上方命令后面加上 應用名

ORM

  • Object Relational Mapping
  • ORM(類、對象、屬性)——DB(數據表、數據行、字段)

流程說明

  1. 創建models
  2. 通過models創建遷移文件(makemigrations)
  3. 通過遷移文件映射到數據庫中(migrate)

將數據庫表格信息展示在django后台

# 在app下的admin.py中進行設置
from django.contrib import admin
from .models import Articles
admin.site.register(Articles)

設置django后台展示出表格更多的列

# 在app文件下的admin.py中進行設置
from django.contrib import admin
from .models import Articles


class AritclesAdmin(admin.ModelAdmin):
    list_display = ['id', 'title', 'content', 'author']


admin.site.register(Articles, AritclesAdmin)

設置django后台表結構顯示中文列名

# 修改app下的模型文件models.py,在字段創建時設置中文名稱
class Articles(models.Model):
    title = models.CharField('標題', max_length=20)
    author = models.CharField('作者', max_length=20)
    content = models.TextField('內容')
  • 設置完成后需要重新對數據庫進行遷移

數據庫表格列字段設置為選項(性別為可選項)

class Students(models.Model):
    choices = [
        ('male', '男'),
        ('female', '女')
    ]

    name = models.CharField(verbose_name='姓名', max_length=20, unique=True)
    age = models.CharField(verbose_name='年齡', max_length=10)
    gender = models.CharField(verbose_name='性別', max_length=10, choices=choices, default='male')
    is_deleted = models.BooleanField(default=False)
    introduce = models.TextField(verbose_name='自我介紹')

模型中的元數據(Meta)

設置django后台表名顯示為中文

# 在app下的模型文件models.py中進行設置
class Articles(models.Model):
    title = models.CharField('標題', max_length=20)
    author = models.CharField('作者', max_length=20)
    content = models.TextField('內容')

    def __str__(self):
        return self.title

    class Meta:
        verbose_name_plural = '新聞列表'
        verbose_name = '新聞'
  • 在表格模型定義中增加子類Meta,通過verbose_name_plural與verbose_name設置中文名稱即可

設置django后台表結構列名的排序方式

# 在模型定義下的Meta子類中增加ordering字段進行設置
    class Meta:
        verbose_name_plural = '用戶列表'
        verbose_name = '用戶'
        ordering = ['age', '-name']
        # ordering = ['-id']

修改表格名稱

# 同樣是在Mate子類中增加db_table字段進行設置
    class Meta:
        verbose_name_plural = '用戶列表'
        verbose_name = '用戶'
        ordering = ['age', '-name']
        db_table = 'students'

數據查詢(從數據庫中獲取數據)

流程

  • Model(database) → QuerySet(views → context) → html(templates)

查詢表中全部數據

# 在視圖views定義中,通過context傳遞給需要渲染的html
from django.shortcuts import render
from .models import Students
# Create your views here.


def index(request):
    student_list = Students.objects.all()    # 此處為獲取表中所有數據
    context = {
        'students': student_list
    }
    return render(request, 'index.html', context)
# 在模板templates下的index.html中進行展示
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% for student in students %}
    <h1>{{ student.name }}——{{ student.age }}</h1>
{% endfor %}
</body>
</html>
  • 需要配置好urls,此處忽略配置urls的內容,需要根據實際情況自行設置

查詢表中某一條數據

# 在視圖views定義中,通過context傳遞給需要渲染的html
from django.shortcuts import render
from .models import Magnate
# Create your views here.


def index(request):
    context = {
        'result': Magnate.objects.get(pk=1)    # 此處查詢的值必須是唯一的
    }
    return render(request, 'index.html', context)
# 在模板templates下的index.html中進行展示
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>{{ result.name }}</h1>
    <h1>{{ result.age }}</h1>
    <h1>{{ result.gender }}</h1>
    <h1>{{ result.assets }}</h1>
    <h1>{{ result.company }}</h1>
</body>
</html>

查詢表中多條數據(過濾條件的使用)

# 在視圖views定義中,通過context傳遞給需要渲染的html
from django.shortcuts import render
from .models import Magnate
# Create your views here.


def index(request):
    context = {
        'female_list': Magnate.objects.filter(gender='female')
        # 'male_list': Magnate.objects.exclude(gender='female')
    }
    return render(request, 'index.html', context)
# 在模板templates下的index.html中進行展示
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% for female in female_list %}
    <h1>{{ female.name }}——{{ female.assets }}</h1>
{% endfor %}
</body>
</html>
  • filter —— 查詢結果為滿足條件的記錄
  • exclude —— 查詢結果為不滿足條件的記錄

二次查詢(多次查詢)

# 在視圖views定義中,通過context傳遞給需要渲染的html
from django.shortcuts import render
from .models import Magnate
# Create your views here.


def index(request):
    magnates = Magnate.objects.all().filter(gender='male').filter(assets=2125)
    context = {
        'male_list': magnates
    }
    return render(request, 'index.html', context)
# 在模板templates下的index.html中進行展示
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% for male in male_list %}
    <h1>{{ male.name }}——{{ male.assets }}</h1>
{% endfor %}
</body>
</html>

查詢后排序

# 在視圖views定義中,通過context傳遞給需要渲染的html
from django.shortcuts import render
from .models import Magnate
# Create your views here.


def index(request):
    magnates = Magnate.objects.filter(gender='male').order_by('-age')
    context = {
        'magnates': magnates
    }
    return render(request, 'index.html', context)
# 在模板templates下的index.html中進行展示
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% for magnate in magnates %}
    <h1>{{ magnate.name }}——{{ magnate.gender }}——{{ magnate.age }}</h1>
{% endfor %}
</body>
</html>

通過某個字段進行查詢

# 在視圖views定義中,通過context傳遞給需要渲染的html
from django.shortcuts import render
from .models import Magnate
# Create your views here.


def index(request):
    magnates = Magnate.objects.values('name', 'assets')
    context = {
        'magnates': magnates
    }
    return render(request, 'index.html', context)
# 在模板templates下的index.html中進行展示
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% for magnate in magnates %}
    <h1>{{ magnate.name }}——{{ magnate.gender }}——{{ magnate.age }}</h1>
{% endfor %}
</body>
</html>
  • 此處界面不會顯示性別信息,因為在視圖中查詢時只設置了姓名與資產兩個字段
  • values() 后括號為空時,查詢所有字段,等價於 all()
  • values與all的區別為,前者以字典形式返回,后者以對象形式返回

模糊查詢

以xxx開頭或以xxx結尾

# views視圖中filter括號中使用模糊匹配的字段即可
magnates = Magnate.objects.filter(company__startswith='阿里')
  • 字段名__startswith:以xxx開頭,對大小寫敏感
  • 字段名__isstartswith:以xxx開頭
  • 字段名__endswith:以xxx結尾,對大小寫敏感
  • 字段名__isendswith:以xxx結尾

in查詢

# views視圖中filter括號中使用 字段名__in 即可
results = Magnate.objects.filter(age__in=[45, 58, 50])

范圍查詢

# views視圖中filter括號中使用范圍查詢的字段即可
results = Magnate.objects.filter(age__range=(20, 45))
  • 范圍查詢使用元組用來表示范圍,只適用於數值型字段

判斷條件查詢

# views視圖中filter括號中使用條件判斷的字段即可
results = Magnate.objects.filter(assets__gt=1000)
  • 字段名__gt:大於
  • 字段名__gte:大於等於
  • 字段名__lt:小於
  • 字段名__lte:小於等於

向數據庫中插入數據

# 在視圖views定義中,通過create設置需要插入的數據
Magnate.objects.create(name='AlexLu', age=50, gender='male', assets=666, company='創慧弘', introduce='CHH Co., Ltd.')

數據統計

# 在視圖views定義中,通過count進行統計
from django.shortcuts import render
from .models import Magnate
# Create your views here.


def index(request):
    magnates = Magnate.objects.filter(gender='male').count()
    context = {
        'count': magnates
    }
    return render(request, 'index.html', context)
# 在模板templates下的index.html中進行展示
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
	<h1>{{ count }}</h1>
</body>
</html>

Count - Sum - Avg - Max - Min

# 需要在視圖中導入相關統計函數
from django.db.models import Count, Sum, Avg, Max, Min
# 在視圖中統計時通過aggregate進行調用
results = Magnate.objects.aggregate(Count('name'), Sum('assets'), Avg('assets'), Max('assets'), Min('assets'))
  • 返回值為字典形式:
{'name__count': 10, 'assets__sum': 14446, 'assets__avg': 1444.6, 'assets__max': 2387, 'assets__min': 400}
  • 也可通過filter過濾后調用對應的統計函數實現

表單

1. 創建表單

# 在應用下創建forms.py
from django import forms


class RegisterForms(forms.Form):
    user_name = forms.CharField(min_length=8, max_length=20, label='用戶名', initial='請輸入您的手機號/密碼')
    password = forms.CharField(widget=forms.PasswordInput, min_length=8, max_length=16, label='密碼', help_text='密碼為8-16位數字字母組合')
    repassword = forms.CharField(widget=forms.PasswordInput, min_length=8, max_length=16, label='確認密碼')
    age = forms.IntegerField(min_value=18, max_value=100, label='年齡')
    # age = forms.Field(widget=forms.NumberInput, label='年齡')
    email = forms.EmailField(label='郵箱', disabled=True)
    phone = forms.CharField(max_length=11, label='手機號碼', label_suffix=':(+86)')
    introduce = forms.CharField(label='自我介紹', widget=forms.Textarea)

2. 創建表單視圖(將表單傳遞到前端頁面)

# 在應用下的views.py中進行創建
from django.shortcuts import render
from .forms import RegisterForms
from django.views import View


class IndexForms(View):
    def get(self, request):
        forms = RegisterForms()
        return render(request, 'index.html', {'forms': forms})

3. 配置路由

# 在應用下的urls.py中進行配置
urlpatterns = [
    path('', views.IndexForms.as_view(), name='form'),
]

4. 編寫前端頁面代碼

{# 在應用下templates中創建index.html進行編寫 #}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="" method="post">
        <table>
            {{ forms.as_table }}    {#渲染成表格#}
            <tr>
                <td><input type="submit" value="確認登陸" name="submit"></td>
            </tr>
        </table>
    </form>

<hr>

    <form action="" method="post">
        <div>
            {{ forms.as_p }}    {#渲染成段落#}
            <td><input type="submit" value="確認登陸" name="submit"></td>
        </div>
    </form>

<hr>

    <form action="" method="post">
        <div>
            {{ forms.as_ul }}    {#渲染成標簽#}
            <td><input type="submit" value="確認登陸" name="submit"></td>
        </div>
    </form>
</body>
</html>

5. 前端界面美化(增加CSS樣式)

方法一

{# 直接在index.html文件中增加樣式 #}
{# 在<head>標簽中增加<style>標簽設置相應控件的樣式 #}
<style>
    #id_username{
        border-radius: 5px;
    }
</style>

方法二

# 在表單文件forms.py中為控件綁定樣式類
from django import forms


class RegisterForms(forms.Form):
    username = forms.CharField(min_length=8, max_length=20, label='用戶名', initial='請輸入您的手機號/密碼', widget=forms.TextInput(attrs={'class': 'custom-forms'}))
    password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='密碼', help_text='密碼為8-16位數字字母組合')
    repassword = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='確認密碼')
    age = forms.IntegerField(min_value=18, max_value=100, label='年齡', widget=forms.TextInput(attrs={'class': 'custom-forms'}))
    # age = forms.Field(widget=forms.NumberInput, label='年齡')
    email = forms.EmailField(label='郵箱', disabled=True, widget=forms.TextInput(attrs={'class': 'custom-forms'}))
    phone = forms.CharField(max_length=11, label='手機號碼', label_suffix=':(+86)', widget=forms.TextInput(attrs={'class': 'custom-forms'}))
    introduce = forms.CharField(label='自我介紹', widget=forms.Textarea(attrs={'class': 'custom-forms-textarea'}))
{# 在<head>標簽中增加<style>標簽設置控件對應樣式類的屬性 #}
<style>
    .custom-forms{
        border-radius: 5px;
    }
    .custom-forms-textarea{
        border-radius: 15px;
    }
</style>

6. 選擇控件

# 直接在表單文件form.py中定義控件時設置
from django import forms


class RegisterForms(forms.Form):
    choices_item = [
        (1, '男'), (2, '女'), (3, '保密')
    ]
    # 下拉列表
    gender = forms.ChoiceField(label='性別', choices=choices_item, nitial=3)
    # 單選
    gender2 = forms.ChoiceField(label='性別', choices=choices_item, widget=forms.RadioSelect, initial=2)
    # 復選
    gender3 = forms.MultipleChoiceField(label='性別', choices=choices_item, widget=forms.CheckboxSelectMultiple, initial=1)

7. 日期控件

from django import forms


class RegisterForms(forms.Form):
    formats = [
        '%Y-%m-%d',  # '2019-6-30'
        '%m/%d/%Y',  # '06/30/2019'
        '%m/%d/%y',  # '06/30/19'
    ]
    # 日期輸入框
    birthday = forms.DateField(label='出生日期', input_formats=formats)

    year_list = [
        1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
    ]
    # 日期選擇框
    birthday2 = forms.DateField(label='出生日期', input_formats=formats, widget=forms.SelectDateWidget(years=year_list))

日期控件數據驗證

# 在應用下的views.py中的控件類視圖中通過forms.is_valid()進行驗證
from django.shortcuts import render, HttpResponse
from .forms import RegisterForms
from django.views import View


class IndexForms(View):
    def get(self, request):
        forms = RegisterForms()
        return render(request, 'index.html', {'forms': forms})

    def post(self, request):
        forms = RegisterForms(request.POST)
        if forms.is_valid():
            birthday = forms.cleaned_data.get('birthday')
            return render(request, 'home.html', {'birthday': birthday})
        else:
            return HttpResponse('<h1>對不起,您輸入的出生日期有誤~!</h1>')
{# 可通過home.html獲取數據並展示 #}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>歡迎登陸Django后台管理系統</title>
</head>
<body>
<h1>{{ birthday }}</h1>
</body>
</html>

8. 獲取表單數據

# django項目的應用下的forms.py
from django import forms


class RegisterForms(forms.Form):
    choices_item = [
        (1, '男'), (2, '女'), (3, '保密')
    ]
    hobbies = [
        (1, '足球'), (2, '籃球'), (3, 'Python')
    ]
    year_list = [
        1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
    ]

    username = forms.CharField(min_length=8, max_length=20, label='用戶名', initial='請輸入您的手機號/密碼', widget=forms.TextInput(attrs={'class': 'custom-forms'}))
    password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='密碼', help_text='密碼為8-16位數字字母組合')
    repassword = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='確認密碼')
    gender = forms.ChoiceField(label='性別', choices=choices_item, nitial=3)
    age = forms.IntegerField(min_value=18, max_value=100, label='年齡', widget=forms.NumberInput(attrs={'class': 'custom-forms'}))
    birthday = forms.DateField(required=False, label='出生日期', widget=forms.SelectDateWidget(years=year_list))
    hobby = forms.MultipleChoiceField(label='愛好', choices=hobbies, widget=forms.CheckboxSelectMultiple)
    introduce = forms.CharField(label='自我介紹', widget=forms.Textarea(attrs={'class': 'custom-forms-textarea'}))
# 應用下的視圖文件views.py中編寫表單對應的類視圖
from django.shortcuts import render, HttpResponse
from .forms import RegisterForms
from django.views import View


class IndexForms(View):
    def get(self, request):
        forms = RegisterForms()
        return render(request, 'index.html', {'forms': forms})

    def post(self, request):
        forms = RegisterForms(request.POST)
        if forms.is_valid():
            username = forms.cleaned_data.get('username')
            password = forms.cleaned_data['password']
            context = {
                # 以字典形式處理表單數據
                'datalist': {
                    'username': username,
                    'password': password,
                    'repassword': repassword,
                    'age': age,
                    'gender': gender,
                    'birthday': birthday,
                    'hobby': hobby,
                    'introduce': introduce,
                },
                # 以列表形式處理表單數據
                'datalist2': [
                    username,
                    password,
                    repassword,
                    age,
                    gender,
                    birthday,
                    hobby,
                    introduce,
                ],
            }
            return render(request, 'home.html', context=context)
        else:
            return HttpResponse('<h1>對不起,您輸入的信息有誤~!</h1>')
{# 通過home.html接收表單數據並展示 #}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>歡迎登陸Django后台管理系統</title>
</head>
<body>

{#接收字典形式數據#}
{% for k, v in datalist.items %}
    <h1>{{ k }}---{{ v }}</h1>
{% endfor %}

<hr>

{#接收列表形式數據#}
{% for field in datalist2 %}
    <h1>{{ field }}</h1>
{% endfor %}

</body>
</html>

模型表單(ModelForm)

1. 在模型文件models.py中設置好數據庫映射

from django.db import models


class Magnate(models.Model):
    choices = [
        ('male', '男'),
        ('female', '女')
    ]

    name = models.CharField(verbose_name='姓名', max_length=20, unique=True)
    age = models.CharField(verbose_name='年齡', max_length=10)
    gender = models.CharField(verbose_name='性別', max_length=10, choices=choices, default='male')
    assets = models.IntegerField(verbose_name='資產')
    company = models.CharField(verbose_name='公司', max_length=50)
    is_deleted = models.BooleanField(default=False)
    introduce = models.TextField(verbose_name='介紹')

    class Meta:
        verbose_name_plural = '富豪榜'
        verbose_name = '富豪'
        ordering = ['id']

2. 建立模型表單

# 在應用下的forms.py中進行建立
from django import forms
from .models import Magnate


class MagnatesForms(forms.ModelForm):
    class Meta:
        model = Magnate
        # 獲取全部字段
        # fields = '__all__'
        # 指定過濾掉字段‘isdeleted’
        # exclude = ['is_deleted']
        # 指定獲取的字段列表
        fields = ['name', 'age', 'assets', 'company']

3. 創建模型表單對應的視圖

# 在應用下的views.py中進行創建
from django.shortcuts import render, HttpResponse
from .models import Magnate
from .forms import MagnatesForms
from django.views import View


class IndexMagnate(View):
    def get(self, request):
        forms = MagnatesForms()
        return render(request, 'index.html', {'forms': forms})

4. 前端頁面展示模型表單

{# 在應用中templates下的index.html進行展示 #}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .custom-forms{
            border-radius: 5px;
        }
        .custom-forms-textarea{
            border-radius: 15px;
        }
    </style>
</head>
<body>
    <form action="" method="post">
        <div>
            {{ forms.as_p }}    {#渲染成段落#}
            <td><input type="submit" value="確認登陸" name="submit"></td>
        </div>
    </form>
</body>
</html>

5. 為模型表單頁面配置路由

# 在項目的路由文件urls.py中通過include關聯到應用路由
from django.contrib import admin
from django.urls import path, include
from news import urls as news_urls

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(news_urls)),
]
# 在應用下的路由文件urls.py中將創建的模型表單視圖與路徑進行匹配
from django.urls import path
from news import views

urlpatterns = [
    path('', views.IndexMagnate.as_view(), name='magnate'),
]

為模型表單增加字段

# 直接在forms.py中的模型表單定義中增加
# 此處增加了password與repassword兩個字段
from django import forms
from .models import Magnate


class MagnatesForms(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='密碼', help_text='密碼為8-16位數字字母組合')
    repassword = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='確認密碼')

    class Meta:
        model = Magnate
        # 獲取全部字段
        # fields = '__all__'
        # 指定過濾掉字段‘isdeleted’
        # exclude = ['is_deleted']
        # 指定獲取的字段列表————可用來調整顯示順序
        fields = ['name', 'gender', 'age', 'password', 'repassword', 'assets', 'company']

為模型表單渲染CSS樣式

# 直接在forms.py中的模型表單定義下增加widgets通過字典為相應的字段綁定控件及CSS樣式
from django import forms
from .models import Magnate


class MagnatesForms(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='密碼', help_text='密碼為8-16位數字字母組合')
    repassword = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='確認密碼')

    class Meta:
        model = Magnate
        # 獲取全部字段
        # fields = '__all__'
        # 指定過濾掉字段‘isdeleted’
        # exclude = ['is_deleted']
        # 指定獲取的字段列表————可用來調整顯示順序
        fields = ['name', 'gender', 'age', 'password', 'repassword', 'assets', 'company']
        widgets = {
            'name': forms.TextInput(attrs={'class': 'custom-textinput'}),
            'introduce': forms.Textarea(attrs={'class': 'custom-textinput', 'row': 30, 'cols': 80}),
        }
{# 在html中為控件設定CSS樣式 #}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .custom-forms{
            border-radius: 5px;
        }
        .custom-forms-textarea{
            border-radius: 15px;
        }
        .custom-textinput{
            border: 5px solid #00ff00;
            border-radius: 5px;
        }
    </style>
</head>
<body>
    <form action="" method="post">
        <div>
            {{ forms.as_p }}    {#渲染成段落#}
            <td><input type="submit" value="確認登陸" name="submit"></td>
        </div>
    </form>
</body>
</html>

表單的手動渲染

普通表單的手動渲染

# 利用前端知識在html中直接進行樣式設置
<form action="" method="post">
    <hr>
    <ul>
        <li style="list-style-type: none;">
            <span style="color: #ff0000">
                {{ forms.username.label }} :
            </span>
            <span>
                {{ forms.username }}
            </span>
            <span style="margin-left: 10px">
                {{ forms.username.help_text }}
            </span>
        </li>
    </ul>
    <hr>
    <td><input type="submit" value="確認登陸" name="submit"></td>
</form>

模型表單的手動渲染

# 直接在模型表單定義中增加前端需要界面展示的信息,並在html中進行渲染
from django import forms
from .models import Magnate


class MagnatesForms(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='密碼', help_text='密碼為8-16位數字字母組合')
    repassword = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='確認密碼')

    class Meta:
        model = Magnate
        # 獲取全部字段
        # fields = '__all__'
        # 指定過濾掉字段‘isdeleted’
        # exclude = ['is_deleted']
        # 指定獲取的字段列表————可用來調整顯示順序
        fields = ['name', 'gender', 'age', 'password', 'repassword', 'assets', 'company']
        widgets = {
            'name': forms.TextInput(attrs={'class': 'custom-textinput'}),
            'introduce': forms.Textarea(attrs={'class': 'custom-textinput', 'row': 30, 'cols': 80}),
        }
        help_texts = {
            'name': '請輸入中文姓名全稱',
        }
        labels = {
            'name': '中文姓名',
        }

模型表單的數據保存(MySQL)

# 連接好MySQL數據庫,在模型表單視圖中post方法內進行數據獲取和保存
from django.shortcuts import render, HttpResponse
from .models import Magnate
from .forms import MagnatesForms
from django.views import View


class IndexMagnate(View):
    def get(self, request):
        forms = MagnatesForms()
        return render(request, 'index.html', {'forms': forms})

    def post(self, request):
        forms = MagnatesForms(request.POST)
        if forms.is_valid():
            forms.save()
            return HttpResponse('<h1>數據保存成功!</h1>')
        else:
            return HttpResponse('<h1>數據保存失敗!</h1>')

未完待續

以上學習筆記是根據視頻教程 Python之Django企業開發實戰 的思路進行初步整理,待內容完整后進行重新梳理。

最后感謝陳老師詳細的教學視頻。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM