您好,登錄后才能下訂單哦!
把數據存取邏輯、業務邏輯和表現邏輯組合在一起的概念有時被稱為軟件架構的Model-View-Controller(MVC)
模式。在這個模式中,Model代表數據存取層,View代表的是系統中選擇顯示什么和怎么顯示的部分,Controller指的是系統中根據用戶輸入并視需要訪問模型,以決定使用哪個視圖的那部分。
Django緊緊地遵循這種MVC
模式,可以稱得上是一種MVC
框架。
以下是Django中M、V
和C
各自的含義:
**M**
: 數據存取部分,由django數據庫層處理;
**V**
: 選擇顯示哪些數據要顯示以及怎樣顯示的部分,由視圖和模板處理;
**C**
: 根據用戶輸入委派視圖的部分,由Django框架根據URLconf設置,對給定URL調用適當的Python函數;
C
由框架自行處理,而Django里更關注的是模型(Model)
、模板(Template)
和視圖(Views)
,Django也被稱為MTV
框架,在MTV開發模式中:
**M**
代表模型(Model),即數據存取層,該層處理與數據相關的所有事務:如何存取、如何驗證有效性、包含哪些行為以及數據之間的關系等;
**T**
代表模板(Template),即表現層,該層處理與表現相關的決定:如何在頁面或其他類型文檔中進行顯示;
**V**
代表視圖(View),即業務邏輯層,該層包含存取模型及調取恰當模板的相關邏輯,你可以把它看作模型與模板之間的橋梁;
Django的數據庫在settings.py
文件中配置,打開這個文件找到DATABASES字段進行數據庫的配置:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mydatabase', 'USER': 'root', 'PASSWORD': 'as', 'HOST': '127.0.0.1', 'PORT': '3306', } }
以下是一個MySQL數據庫的配置屬性:
字段 | 描述 |
---|---|
ENGINE | 使用的數據庫引擎 |
NAME | 數據庫名稱 |
USER | 那個用戶連接數據庫 |
PASSWORD | 用戶的密碼 |
HOST | 數據庫服務器 |
PORT | 端口 |
ENGINE字段所支持的內置數據庫
django.db.backends.postgresql
django.db.backends.mysql
django.db.backends.sqlite3
django.db.backends.oracle
無論你選擇使用那個數據庫都必須安裝此數據庫的驅動,即python操作數據庫的介質,在這里你需要注意的是python3.x
并不支持使用MySQLdb
模塊,但是你可以通過pymysql
來替代mysqldb
,首先你需要安裝pymysql
模塊:
pip3 install pymysql
然后再項目的__init__.py
文件加入以下兩行配置:
import pymysql pymysql.install_as_MySQLdb()
當數據庫配置完成之后,我們可以使用python manage.py shell
進入項目測試,輸入下面這些指令來測試你的數據庫配置:
E:\DarkerProjects>python manage.py shell Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from django.db import connection >>> cursor = connection.cursor()
如果沒有顯示什么錯誤信息,那么你的數據庫配置是正確的。
讓我們來創建一個Django app,一個包含模型,視圖和Django代碼,并且形式為獨立Python包的完整Django應用。
Project和app之間的不同就是一個是配置另一個是代碼:
一個Project包含很多個Django app以及對它們的配置;
技術上,Project的作用是提供配置文件,比方說哪里定義數據庫連接信息, 安裝的app列表,TEMPLATE等等;
一個app是一套Django功能的集合,通常包括模型和視圖,按Python的包結構的方式存在;
例如,Django本身內建有一些app,例如注釋系統和自動管理界面,app的一個關鍵點是它們是很容易移植到其他Project和被多個Project復用。
如果你使用了Django的數據庫層(模型),你必須創建一個Django app,模型必須存放在apps中,因此,為了開始建造我們的模型,我們必須創建一個新的app:
E:\DarkerProjects>python manage.py startapp darker
E:\DarkerProjects
這是我的項目根目錄,創建完成之后會自動創建如下文件:
E:\DarkerProjects>tree /f darker 文件夾 PATH 列表 卷序列號為 0003-4145 E:\DARKERPROJECTS\DARKER │ admin.py │ apps.py │ models.py │ tests.py │ views.py │ __init__.py │ └─migrations __init__.py
首先我們需要創建三張表,分別是:
學生表(student),擁有字段: id/sname/gender
課程表(course),擁有字段: id/cname
成績表(score),擁有字段: id/student_id/course_id
打開app的models.py
目錄輸入以下代碼:
from django.db import models # Create your models here. class student(models.Model): # 自增主鍵 id = models.AutoField sname = models.CharField(max_length=12) gender = models.CharField(max_length=2) class course(models.Model): # 自增主鍵 id = models.AutoField cname = models.CharField(max_length=12) class score(models.Model): # 自增主鍵 id = models.AutoField # 設置外鍵關聯 student_id = models.ForeignKey(student) course_id = models.ForeignKey(course)
每個數據模型都是django.db.models.Model
的子類,它的父類Model
包含了所有必要的和數據庫交互的方法,并提供了一個簡潔漂亮的定義數據庫字段的語法,每個模型相當于單個數據庫表,每個屬性也是這個表中的一個字段,屬性名就是字段名;
要通過django在數據庫中創建這些表,首先我們需要在項目中激活這些模型,將darker app添加到配置文件的已安裝應用列表中即可完成此步驟;
編輯settings.py
文件,找到INSTALLED_APPS
設置,INSTALLED_APPS
告訴Django項目哪些app
處于激活狀態:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'darker', ]
通過下面的指令來創建數據表:
# 檢查是否正確 E:\DarkerProjects>python manage.py check System check identified no issues (0 silenced). # 在數據庫中生成表 E:\DarkerProjects>python manage.py makemigrations Migrations for 'darker': darker\migrations\0002_auto_20160809_1423.py: - Create model course - Create model score - Create model student - Remove field authors from book - Remove field student from book - Delete model Author - Delete model Book - Delete model student - Add field student_id to score # 生成數據 E:\DarkerProjects>python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, darker, sessions Running migrations: Rendering model states... DONE Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying darker.0001_initial... OK Applying darker.0002_auto_20160809_1423... OK Applying sessions.0001_initial... OK
django1.7
之前的版本都是:
python manage.py syncdb
django1.7
及之后的版本做了修改,把1步拆成了2步,變成:
python manage.py makemigrations python manage.py migrate
查看創建的數據表:
mysql> show tables; +----------------------------+ | Tables_in_mydb | +----------------------------+ | auth_group | | auth_group_permissions | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | darker_course | | darker_score | | darker_student | | django_admin_log | | django_content_type | | django_migrations | | django_session | +----------------------------+ 13 rows in set (0.00 sec)
運行python manage.py shell
并使用Django提供的高級Python API
E:\DarkerProjects>python manage.py shell
# 導入student模型類,通過這個類我們可以與student數據表進行交互 >>> from darker.models import student # 創建一個student類的實例并設置了字段sname, gender的值 >>> s1 = student(sname="ansheng", gender="男") # 調用該對象的save()方法,將對象保存到數據庫中,Django會在后臺執行一條INSERT語句 >>> s1.save() # 在插入一條數據 >>> s2 = student(sname="as", gender="女") >>> s2.save() # 使用student.objects屬性從數據庫取出student表的記錄集,這個屬性有許多方法,student.objects.all()方法獲取數據庫中student類的所有對象,實際上Django執行了一條SQL SELECT語句 >>> student_list = student.objects.all() >>> student_list <QuerySet [<student: student object>, <student: student object>]>
我們可以簡單解決這個問題,只需要在上面的三個表類中添加一個方法__str__
,如下:
from django.db import models # Create your models here. class student(models.Model): id = models.AutoField sname = models.CharField(max_length=12) gender = models.CharField(max_length=2) def __str__(self): return self.sname class course(models.Model): id = models.AutoField cname = models.CharField(max_length=12) def __str__(self): return self.cname class score(models.Model): id = models.AutoField student_id = models.ForeignKey(student) course_id = models.ForeignKey(course)
然后ctrl+c
推出shell重新進入
E:\DarkerProjects>python manage.py shell Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from darker.models import student >>> student_list = student.objects.all() >>> student_list # 這次獲取的就是字符串而不是對象了 <QuerySet [<student: ansheng>, <student: as>]>
插入數據
>>> s1 = student(sname="安生", gender="男")
將數據保存到數據庫
>>> s1.save()
獲取剛插入的記錄主鍵id
>>> s1.id 3
修改數據內容
>>> s1.gender="女" >>> s1.save()
相當于執行了下面的SQL指令
UPDATE darker_student SET gender = '女' WHERE id=3;
下面的指令是從數據庫中獲取所有的數據:
>>> student.objects.all() <QuerySet [<student: ansheng>, <student: as>, <student: 安生>]>
Django在選擇所有數據時并沒有使用SELECT*
,而是顯式列出了所有字段,SELECT *
會更慢,而且最重要的是列出所有字段遵循了Python界的一個信條:明言勝于暗示
數據過濾
使用filter()
方法對數據進行過濾
>>> student.objects.filter(sname="安生", gender="女") <QuerySet [<student: 安生>]>
在sname
和contains
之間有雙下劃線,gender部分會被Django翻譯成LIKE語句:
>>> student.objects.filter(sname__contains="a") <QuerySet [<student: ansheng>, <student: as>]>
翻譯成下面的SQL
SELECT id, sname, gender FROM darker_student WHERE name LIKE '%a%';
獲取單個對象
>>> student.objects.get(sname="as") <student: as>
數據排序
使用order_by()
這個方法進行排序
>>> student.objects.order_by("sname") <QuerySet [<student: ansheng>, <student: as>, <student: 安生>]>
如果需要以多個字段為標準進行排序(第二個字段會在第一個字段的值相同的情況下被使用到),使用多個參數就可以了,如下:
>>> student.objects.order_by("sname", "gender") <QuerySet [<student: ansheng>, <student: as>, <student: 安生>]>
我們還可以指定逆向排序,在前面加一個減號 - 前綴:
>>> student.objects.order_by("-sname") <QuerySet [<student: 安生>, <student: as>, <student: ansheng>]>
設置數據的默認排序
如果你設置了這個選項,那么除非你檢索時特意額外地使用了order_by()
,否則,當你使用Django的數據庫API去檢索時,student對象的相關返回值默認地都會按sname
字段排序。
class student(models.Model): id = models.AutoField sname = models.CharField(max_length=12) gender = models.CharField(max_length=2) def __str__(self): return self.sname class Meta: ordering = ['sname']
連鎖查詢
>>> student.objects.filter(id="2").order_by("-sname") <QuerySet [<student: as>]>
限制返回的數據
>>> student.objects.order_by('sname')[0] <student: ansheng> >>> student.objects.order_by('sname')[1] <student: as>
類似的,你可以用Python的列表切片來獲取數據:
>>> student.objects.order_by('sname')[0:2] <QuerySet [<student: ansheng>, <student: as>]>
雖然不支持負索引,但是我們可以使用其他的方法,比如,稍微修改order_by()
語句來實現:
>>> student.objects.order_by('-sname')[0] <student: 安生>
更改某一指定的列,我們可以調用結果集(QuerySet)對象的update()
方法:
>>> student.objects.filter(id=2).update(sname='Hello') 1
update()
方法對于任何結果集(QuerySet)均有效,這意味著你可以同時更新多條記錄,一下實例將所有的性別都改成女:
>>> student.objects.all().update(gender='女') 3
update()方法會返回一個整型數值,表示受影響的記錄條數
刪除數據庫中的對象只需調用該對象的delete()
方法。
刪除指定數據
>>> student.objects.all().filter(sname="ansheng").delete(); (1, {'darker.student': 1, 'darker.score': 0}) >>> student.objects.all() <QuerySet [<student: Hello>, <student: hello>, <student: 安生>]>
刪除所有數據
>>> student.objects.all().delete() (3, {'darker.student': 3, 'darker.score': 0}) >>> student.objects.all() <QuerySet []>
屬性 | 描述 |
---|---|
models.AutoField | 自增列,默認會生成一個id列,如果要顯示的自定義一個自增列,必須將給列設置為主鍵primary_key=True |
models.CharField | 字符串字段,必須有max_length 參數 |
models.BooleanField | 布爾類型,不能為空,Blank=True |
models.ComaSeparatedIntegerField | 用逗號分割的數字,必須有max_lenght 參數 |
models.DateField | 日期類型,對于參數,auto_now = True 則每次更新都會更新這個時間;auto_now_add 則只是第一次創建添加,之后的更新不再改變 |
models.DateTimeField | 日期類型datetime 同DateField 的參數 |
models.Decimal | 十進制小數類型,必須指定整數位max_digits 和小數位decimal_places |
models.EmailField | 字符串類型(正則表達式郵箱) |
models.FloatField | 浮點類型 |
models.IntegerField | ××× |
models.BigIntegerField | 長××× |
models.IPAddressField | 字符串類型(ip4正則表達式) |
models.GenericIPAddressField | 字符串類型(ip4和ip6是可選的),參數protocol可以是:both、ipv4、ipv6,驗證時,會根據設置報錯 |
models.NullBooleanField | 允許為空的布爾類型 |
models.PositiveIntegerFiel | 正Integer |
models.PositiveSmallIntegerField | 正smallInteger |
models.SlugField | 減號、下劃線、字母、數字 |
models.SmallIntegerField | 數字,數據庫中的字段有:tinyint、smallint、int、bigint |
models.TextField | 字符串 |
models.TimeField | 時間 |
models.URLField | 字符串,地址正則表達式 |
models.BinaryField | 二進制 |
models.ImageField | 圖片 |
models.FilePathField | 文件 |
方法 | 描述 | |
---|---|---|
null=True | 數據庫中字段是否可以為空 | |
blank=True | django的 Admin 中添加數據時是否可允許空值 | |
primary_key = False | 主鍵,對AutoField設置主鍵后,就會代替原來的自增 id 列 | |
auto_now | 自動創建—-無論添加或修改,都是當前操作的時間 | |
auto_now_add | 自動創建—-永遠是創建時的時間 | |
max_length | 最大值 | |
default | 默認值 | |
verbose_name | Admin中字段的顯示名稱 | |
name豎線db_column | 數據庫中的字段名稱 | |
unique=True | 不允許重復 | |
db_index = True | 數據庫索引 | |
editable=True | 在Admin里是否可編輯 | |
error_messages=None | 錯誤提示 | |
auto_created=False | 自動創建 | |
help_text | 在Admin中提示幫助信息 |
方法 | 描述 |
---|---|
models.ForeignKey(其他表) | 一對多 |
models.ManyToManyField(其他表) | 多對多 |
models.OneToOneField(其他表) | 一對一 |
#Python全棧之路 #Django
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。