title: Python-初識Django開發
date: 2019-07-10 13:27:13
tags:
- Python
- Django
categroies:
- Python
Python=3.7.3 & Django=2.2.3
初識框架
MVC
- M表示model,主要用於對數據庫層的封裝
- V表示view,用於向用戶展示結果
- C表示controller,是核心,用於處理請求、獲取數據、返回結果
MVC框架的核心思想是:解耦,降低各功能模塊之間的耦合性,方便變更,更容易重構代碼,最大程度上實現代碼的重用。
MVT
Django 屬於 MVT 框架。
- M表示model,負責與數據庫交互
- V表示view,是核心,負責接收請求、獲取數據、返回結果
- T表示template,負責呈現內容到瀏覽器
搭建開發環境
創建虛擬環境
virtualenv、virtualenvwrapper、anaconda。
資料:Python基礎42-虛擬環境(創建/激活/操作/刪除-virtualenv、Pycharm、virtualenvwrapper、pipenv)
安裝 Django
創建好虛擬環境,並進入虛擬環境。直接pip3 install django
就可以,如果要指定版本pip3 install django=1.8.1
。
安裝好後可以使用pip3 list
查看是否下載好Django 包。
[外鏈圖片轉存失敗(img-MkWWY08E-1562761134575)(https://i.loli.net/2019/07/10/5d257bfd3cdab44108.png)]
創建項目
django-admin startproject test2
,創建出一個 test2 目錄如下圖,其中文件的意思是:
- manage.py:一個命令行工具,可以使用多種方式對Django項目進行交互
- 內層的目錄:項目的真正的Python包
- __init__.py:一個空文件,它告訴Python這個目錄應該被看做一個Python包
- settings.py:項目的配置
- urls.py:項目的URL聲明,我理解的是路由 router,根據 url 進行跳轉。
- wsgi.py:項目與 WSGI 兼容的Web服務器入口
[外鏈圖片轉存失敗(img-BuDoRXHJ-1562761134576)(https://i.loli.net/2019/07/10/5d257da1a5d0b48598.png)]
Models 模型
Django 中 Models 主要是對數據庫的一些操作(增刪改查唄?),如筆記最開始的第一張圖所示。
Django 支持的數據庫包括:sqlite、mysql 等主流數據庫,默認使用的示 sqlite 數據庫。在settings.py文件中,通過 DATABASES 項進行數據庫設置。
創建應用
在一個項目中可以創建一到多個應用,每個應用進行一種業務處理。
python manage.py startapp booktest
[外鏈圖片轉存失敗(img-w2OY00AQ-1562761134578)(https://i.loli.net/2019/07/10/5d25831a2752242843.png)]
定義模型類
在 models.py 中定義模型類,模型類繼承自 Django 的 models.Model 類。
每一個模型類對應一張數據表,主鍵是 Django 自己生成的自動增長類型,所以不用管主鍵。
模型類的類成員就是這張數據表中的屬性。
**【注】**使用 vscode、pycharm 等工具要配置一下當前是用的是虛擬環境中的 Python。
"""models.py"""
from django.db import models
# Create your models here.
# 學校表
class School(models.Model):
# 學校名
school_name = models.CharField(max_length=30)
# 學校地址
school_addr = models.CharField(max_length=30)
# 建校日期
school_build_date = models.DateTimeField()
class Student(models.Model):
# 學生名
stu_name = models.CharField(max_length=20)
# 學生出生日期
stu_birth = models.DateTimeField()
# 學生性別
stu_gender = models.BooleanField()
# 學生是哪個學校的
stu_school = models.ForeignKey('School', on_delete=None)
生成數據表
-
激活模型
編輯 settings.py 文件,將 booktest 應用加入到 INSTALLED_APPS 中
-
生成遷移文件:根據模型類生成sql語句
python3 manage.py makemigrations
-
執行遷移:執行sql語句生成數據表
python3 manage.py migrate
[外鏈圖片轉存失敗(img-kSK80ql3-1562761134580)(https://i.loli.net/2019/07/10/5d258990c373d45602.png)]
測試數據表
進入python shell,看看模型(表)是否已經OK。
python manage.py shell
[外鏈圖片轉存失敗(img-wpEpRL2u-1562761134580)(https://i.loli.net/2019/07/10/5d258c1e9332469206.png)]
可以看到打印出來的是這些信息,這裏就可以重寫__str__()
方法了,類似於 Java 中的toString()
方法的作用。下圖爲測試結果。對於 Student 模型也是同理的。
[外鏈圖片轉存失敗(img-wge030rK-1562761134581)(https://i.loli.net/2019/07/10/5d258df68964526735.png)]
b=School.objects.get(pk=1) # pk 表示主鍵,這個是獲取 主鍵 爲1的那條數據對象
b.delete() # 刪除一條數據
關聯對象操作
學生:學校 = n:1
獲得關聯集合:返回當前 School 對象的所有 Student
管理站點
Django 默認提供了後臺管理功能(對數據表增刪改查、增加用戶)
python manage.py runserver ip:port
可以不寫ip,默認端口爲8000,這是一個純python編寫的輕量級web服務器,僅在開發階段使用。
管理操作
站點分爲“內容發佈”和“公共訪問”兩部分。
“內容發佈”的部分負責添加、修改、刪除內容,開發這些重複的功能是一件單調乏味、缺乏創造力的工作。爲此,Django 會根據定義的模型類完全自動地生成管理模塊。
生成一個管理員賬戶:
python manage.py createsuperuser
啓動服務器,通過“127.0.0.1:8000/admin”訪問,輸入上面創建的用戶名、密碼完成登錄
默認可以對groups、users進行管理,不能對創建的模型(表)進行增刪改查。如果要對剛剛定義的模型進行增刪改查的話,要做下面的操作:
-
在 booktest/admin.py 文件中,註冊模型
-
刷新管理頁面,可以對BookInfo的數據進行增刪改查操作
【注】
問題:如果在str方法中返回中文,在修改和添加時會報ascii的錯誤
解決:在str()方法中,將字符串末尾添加“.encode(‘utf-8’)”
管理界面本地化
編輯settings.py文件,設置編碼、時區
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
[外鏈圖片轉存失敗(img-hON0vn96-1562761134587)(https://i.loli.net/2019/07/10/5d2597cda936456378.png)]
自定義管理界面
在 booktest/admin.py 中增加一些代碼實現自定義管理界面。
Django提供了admin.ModelAdmin類,通過定義ModelAdmin的子類,來定義模型在Admin界面的顯示方式。
列表頁屬性
-
list_display:顯示字段,可以點擊列頭進行排序
-
list_filter:過濾字段,過濾框會出現在右側
list_filter = ['school_name']
- search_fields:搜索字段,搜索框會出現在上側
search_fields = ['school_name']
- list_per_page:分頁,分頁框會出現在下側
list_per_page = 10
[外鏈圖片轉存失敗(img-BHP5gTnC-1562761134590)(https://i.loli.net/2019/07/10/5d259af83808122165.png)]
[外鏈圖片轉存失敗(img-uCcPYLbC-1562761134590)(https://i.loli.net/2019/07/10/5d259b8f3cb8a26829.png)]
添加、修改頁屬性
- fields:屬性的先後順序
fields = ['bpub_date', 'btitle']
- fieldsets:屬性分組
fieldsets = [
('base', {'fields': ['school_name', 'school_addr']}),
('else', {'fields': ['school_build_date']})
]
關聯屬性
Student 模型類,有兩種添加數據的方式。第一個就是一個一個創建,然後把外鍵約束給了就行,第二個方法就是在創建 School 模型類對象的時候,直接加入一些 Student 數據。
下面實現關聯註冊:
- 接下來實現關聯註冊
from django.contrib import admin
from models import School, Student
class StudentInline(admin.StackedInline):
model = Student
extra = 2
class School(admin.ModelAdmin):
inlines = [StudentInline]
admin.site.register(BookInfo, BookInfoAdmin)
- 可以將內嵌的方式改爲表格
class StudentInline(admin.TabularInline)
[外鏈圖片轉存失敗(img-u8ZlTCoW-1562761134592)(https://i.loli.net/2019/07/10/5d259e5f74a9a12037.png)]
布爾值的顯示
- 發佈性別的顯示不是一個直觀的結果,可以使用方法進行封裝
def gender(self):
if self.stu_gender:
return '男'
else:
return '女'
gender.short_description = '性別'
- 在admin註冊中使用 gender 代替 stu_gender
class HeroInfoAdmin(admin.ModelAdmin):
list_display = ['id', 'stu_name', 'gender', 'stu_birth']
Views 視圖
在 Django 中,視圖對 Web 請求進行迴應
視圖接收 reqeust 對象作爲第一個參數,包含了請求的信息
視圖就是一個 Python 函數,被定義在 views.py 中
定義完成視圖後,需要配置urlconf,否則無法處理請求
在Django中,定義URLconf包括正則表達式、視圖兩部分
Django使用正則表達式匹配請求的URL,一旦匹配成功,則調用應用的視圖
注意:只匹配路徑部分,即除去域名、參數後的字符串
在 test1/urls.py 插入 booktest,使主 urlconf 連接到 booktest.urls 模塊
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('', include('booktest.urls')),
path('admin/', admin.site.urls),
]
[外鏈圖片轉存失敗(img-akcNpgyC-1562761134594)(https://i.loli.net/2019/07/10/5d25a21c5ea0f75947.png)]
在booktest中新建urls.py並在這個urls.py中添加urlconf
from django.conf.urls import url
from django.urls import path
from . import views
urlpatterns = [
url(r'^$', views.index),
# path('', views.index)
]
[外鏈圖片轉存失敗(img-e6SPGnaA-1562761134594)(https://i.loli.net/2019/07/10/5d25a2e6617df30553.png)]
Templates 模板
模板是html頁面,可以根據視圖中傳遞的數據填充值。
在項目目錄 test2 下創建一個 templates 目錄,裏面再創建一個 app 名文件夾,目錄結構如下:
- 修改settings.py文件,設置TEMPLATES的DIRS值
'DIRS': [os.path.join(BASE_DIR, 'templates')],
-
使用模板
"""views.py""" from django.shortcuts import render # Create your views here. from .models import Student, School def index(req): stu_list = Student.objects.all() context = {'stu_list': stu_list} return render(req, 'booktest/index.html', context=context)
-
在模板中訪問視圖傳遞的數據
{{輸出值,可以是變量,也可以是對象.屬性}}
{%執行代碼段%}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>index page</title>
</head>
<body>
<div>
<h1>index page</h1>
<ul>
{% for i in stu_list %}
<li>
{{ i.stu_name }}
{{ i.stu_birth }}
{{ i.gender }}
{{ i.stu_school }}
</li>
{% endfor %}
</ul>
</div>
</body>
</html>
end.