安裝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(數據表、數據行、字段)
流程說明
- 創建models
- 通過models創建遷移文件(makemigrations)
- 通過遷移文件映射到數據庫中(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企業開發實戰 的思路進行初步整理,待內容完整后進行重新梳理。
最后感謝陳老師詳細的教學視頻。