04-Django模型(1)

  • 2019 年 10 月 11 日
  • 筆記

—恢復內容開始—

模型

  MTV圖解

 

 

 

 ORM

  ORM全拼:Object-Relation-Mapping翻譯就是對象關係映射。在MVC/MTV設計模式中的Model模組中都包括ORM。主要實現模型對象到關係資料庫數據的映射。比如:把資料庫表中每條記錄映射為一個模型對象

 

 

  ORM圖解

 

 

 優點:

  只需要面向對象編程,不需要面向資料庫編寫程式碼。對資料庫的操作都轉化為對類屬性和方法的操作,不用編寫各種資料庫的sql語句

  實現了數據模型與資料庫的解耦,屏蔽了不同資料庫操作上的差異。通過簡單地配置就可以輕鬆更換資料庫,而不需要修改程式碼。

缺點:

  相比較直接使用SQL語句操作資料庫,有性能缺失。會轉化為sql語句在執行。多了流程。根據對象的操作轉換成sql語句,根據查詢的結果轉化成對象,在映射過程中有性能損失。

項目準備

    1、創建項目

django-admin startproject BookManager

  2、創建應用

python manage.py startapp Book

  3、安裝應用

INSTALLED_APPS = [      'django.contrib.admin',      'django.contrib.auth',      'django.contrib.contenttypes',      'django.contrib.sessions',      'django.contrib.messages',      'django.contrib.staticfiles',      'Book',  ]

  4、本地化

LANGUAGE_CODE = 'zh-Hans'    TIME_ZONE = 'Asia/Shanghai'

  5、創建模板路徑

    在應用同級目錄下,創建templates模板文件

TEMPLATES = [      {          'BACKEND': 'django.template.backends.django.DjangoTemplates',          #模板路徑          'DIRS': [os.path.join(BASE_DIR,"templates")],          'APP_DIRS': True,          'OPTIONS': {              'context_processors': [                  'django.template.context_processors.debug',                  'django.template.context_processors.request',                  'django.contrib.auth.context_processors.auth',                  'django.contrib.messages.context_processors.messages',              ],          },      },  ]

6、應用中分發路由

from django.contrib import admin  from django.urls import path  from Book import views  urlpatterns = [      path('admin/', admin.site.urls),      path('booklist/', views.bookList),  ]

7、準備視圖函數

from django.shortcuts import render  from django.http import HttpResponse  # Create your views here.      #書籍列表資訊視圖  def bookList(request):      return HttpResponse("ok")

8、開啟伺服器,測試項目

python manage.py runserver

http://127.0.0.1:8000/

MYSQL資料庫

  Django項目默認採用sqlite3資料庫,但是Web項目首選的資料庫是mysql資料庫,所以我們需要修改Django項目默認的資料庫為mysql資料庫

安裝pymysql包

  pymysql包用於跟mysql資料庫交互,沒有pymysql包會報錯:Error loading MySQLdb module: No module named MySQLdb

pip3 install pymysql

pymysql包配置:

 

 

 

配置項目mysql資料庫(settings.py)

  默認配置:

DATABASES = {      'default': {          'ENGINE': 'django.db.backends.sqlite3',          'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),      }  }

  配置mysql資料庫:

DATABASES = {      'default': {          'ENGINE': 'django.db.backends.mysql',  # 資料庫引擎          'NAME': 'Bookdb',  # 資料庫名稱          'HOST': 'localhost',  # 資料庫主機(建議使用主機真實IP)          'PORT': '3306',  # 資料庫埠          'USER': 'root',  # 資料庫用戶名          'PASSWORD': '',  # 資料庫密碼      }  }

創建項目mysql資料庫

  打開cmd終端,打開資料庫,鏈接資料庫。創建資料庫名字:

create database bookdb charset=utf8;

  use Bookdb;

show tables;

#退出資料庫  exit

欄位類型

  當為項目創建好mysql類型的資料庫bookdb後,需要創建模型類並生成和執行遷移表,從而創建資料庫表。但是在創建模型類需要指定模型屬性和屬性類型。

  模型屬性和屬性類型,也就是對應資料庫中的欄位和欄位類型

模型類定義屬性:

  語法:屬性名 = models.欄位類型(選項)

# 書籍資訊模型  class Book(models.Model):      name = models.CharField(max_length=20) #圖書名稱

備註:屬性名1、不允許使用python的保留關鍵字,2、不允許使用mysql的保留關鍵字,3、不允許使用連續的下劃線,因為Django的查詢語法就是連續的下劃線。

欄位類型

AutoField:自動增長的IntegerField,通常不用指定,不指定時Django會自動創建屬性名為id的自動增長屬性  
BooleanField:布爾欄位,值為True或False
NullBooleanField:支援Null、True、False三種值
CharField(max_length
=字元長度):字元串參數max_length表示最大字元個數
TextField:大文本欄位,一般超過4000個字元時使用
IntegerField:整數
DecimalField(max_digits
=None, decimal_places=None):可以指定精度的十進位浮點數 參數max_digits表示總位數 參數decimal_places表示小數位數
FloatField:浮點數
DateField[auto_now
=False, auto_now_add=False]):日期,參數auto_now表示每次保存對象時,自動設置該欄位為當前時間,用於"最後一次修改"的時間戳,
它總是使用當前日期,默認為false 參數auto_now_add表示當對象第一次被創建時自動設置當前時間,用於創建的時間戳,它總是使用當前日期,默認為false 參數auto_now_add和auto_now是相互排斥的,組合將會發生錯誤
TimeField:時間,參數同DateField
DateTimeField:日期時間,參數同DateField
FileField:上傳文件欄位
ImageField:繼承於FileField,對上傳的內容進行校驗,確保是有效的圖片

選項

通過選項實現對欄位的約束  null:如果為True,表示允許為空,默認值是False
blank:如果為True,則該欄位允許為空白,默認值是False
對比:null是資料庫範疇的概念,blank是表單驗證範疇的
db_column:欄位的名稱,如果未指定,則使用屬性的名稱
db_index:若值為True, 則在表中會為此欄位創建索引,默認值是False
default:默認值
primary_key:若為True,則該欄位會成為模型的主鍵欄位,默認值是False,一般作為AutoField的選項使用
unique:如果為True, 這個欄位在表中必須有唯一值,默認值是False
注意:Django會自動為表創建主鍵欄位 如果使用選項設置某屬性為主鍵欄位後,Django不會再創建自動增長的主鍵欄位 默認創建的主鍵欄位為id,可以使用pk代替,pk全拼為primary key

關係欄位類型

關係型資料庫的關係包括三種類型:
  ForeignKey:一對多,將欄位定義在多的一端中   

  ManyToManyField:多對多,將欄位定義在任意一端中
  

OneToOneField:一對一,將欄位定義在任意一端中
可以維護遞歸的關聯關係,使用self指定,詳見“自關聯”

元模型類

  作用:在模型類中定義 元類Meta,用於設置元資訊,用db_table 自定義表的名字

 # 書籍資訊模型    class BookInfo(models.Model):        name = models.CharField(max_length=20) #圖書名稱          class Meta: #元資訊類            db_table = 'bookinfo' #自定義表的名字

#在資料庫中更改表名

查看錶結構(資料庫的客戶端查看)

desc 表明 

定義模型

  定義的模型可以是這個樣子

#書籍資訊  ("與時間做朋友","2002-08-22","45.21","中信出版社","athor_id")    #人物資訊  ("李笑來","","年齡","家庭地址","電話")

因此模型程式碼如下:

from django.db import models    # Create your models here.  #創建作者資訊表  class Authors(models.Model):      name = models.CharField(max_length=20)#作者名字      gender = models.BooleanField(default=True)#性別      age = models.IntegerField()#年齡      addr = models.CharField(max_length=60)      tel = models.IntegerField()      #元類修改表名      class Meta:          db_table = "authors"    #創建書籍資訊  class Books(models.Model):      name = models.CharField(max_length=20)#書名      pub_data = models.DateField(null=True)#出版日期      #參數max_digits表示總位數 參數decimal_places表示小數位數      price = models.DecimalField(max_digits=8,decimal_places=2)#價格      publish = models.CharField(max_length=20)      #外鍵 將欄位定義在多的一端中 級聯刪除      author = models.ForeignKey(Authors,on_delete=models.CASCADE)      #修改表名(元類)      class Meta:          db_table = "books"

模型遷移不要忘記:

python manage.py makemigrations    python manage.py migrate

查看錶結構:

 

 

去站點插點數據(如果嫌慢就用sql語句插數據)(需要設置站點,1、註冊管理模型類,需要顯示完整的,重寫類,list_display重新註冊,啟動超級用戶,python manage.py createsuperuser)

 

 

 

 展示模型數據

  網址:http://127.0.0.1:8000/booklist

  路由部分:

from django.contrib import admin  from django.urls import path  from Book import views  urlpatterns = [      path('admin/', admin.site.urls),      path('booklist/', views.bookList),  ]

  視圖部分:

from django.shortcuts import render  from django.http import HttpResponse  # Create your views here.  from Book.models import *    #書籍列表資訊視圖  def bookList(request):      #查詢資料庫書籍資訊      booklist = Books.objects.all()      #構造上下文      content = {"booklist":booklist}      #傳入模板 返回由視圖發送給瀏覽器      return render(request,"Book/booklist.html",content)

  模板部分:

from django.db import models    # Create your models here.  #創建作者資訊表  class Authors(models.Model):      name = models.CharField(max_length=20)#作者名字      gender = models.BooleanField(default=True)#性別      age = models.IntegerField()#年齡      addr = models.CharField(max_length=60)      tel = models.IntegerField()      #元類修改表名      class Meta:          db_table = "authors"      def __str__(self):          return self.name  #創建書籍資訊  class Books(models.Model):      name = models.CharField(max_length=20)#書名      pub_data = models.DateField(null=True)#出版日期      #參數max_digits表示總位數 參數decimal_places表示小數位數      price = models.DecimalField(max_digits=8,decimal_places=2)#價格      publish = models.CharField(max_length=20)      #外鍵 將欄位定義在多的一端中 級聯刪除      author = models.ForeignKey(Authors,on_delete=models.CASCADE)      #修改表名(元類)      class Meta:          db_table = "books"        def __str__(self):          return self.name

   結果:

 

 

 模型中重要的實例方法和屬性

  模型實例方法

str : 在將對象轉換成字元串時會被調用    save : 將模型對象保存到資料庫表中    delete : 將模型對象從資料庫表中刪除

  objects模型屬性

objects : 管理器對象是Manager類型的對象,定義在from django.db import models中用於模型對象和資料庫交互
是默認自動生成的屬性,但是可以自定義管理器對象自定義管理器對象後,Django不再生成默認管理器對象objects

自定義管理器對象,原本默認的是objects = models.Manager(),可以自定義,重新實例化管理器對象。

查詢操作

  • 查詢集:表示從資料庫中獲取的模型對象集合
    • 在管理器上調用過濾器方法會返回查詢集
    • 查詢集可以含有0個、一個或多個過濾器
  • 過濾器:基於所給的參數限制查詢的結果
  • 提示:從sql的角度,查詢集和select語句等價,過濾器像where和limit語句

返回列表的過濾器如下: 

all():返回所有的數據  filter():返回滿足條件的數據  exclude():返回滿足條件之外的數據,相當於sql語句中where部分的not關鍵字  order_by():返回排序後的數據

返回單個對象的過濾器如下:

get():返回單個滿足條件的對象  如果未找到會引發"模型類.DoesNotExist"異常  如果多條被返回,會引發"模型類.MultipleObjectsReturned"異常  count():返回當前查詢的總條數  aggregate():聚合  exists():判斷查詢集中是否有數據,如果有則返回True,沒有則返回False

查詢集的特點

  1、惰性執行:創建查詢集不會訪問資料庫,直到在模板中調用數據時,才會訪問資料庫。

調用數據的情況包括迭代、序列化、與if合用

  2、快取:查詢集的結果被存下來之後,再次查詢相同數據時會使用之前快取的數據

 每個查詢集都包含一個快取來最小化對資料庫的訪問,第一次查詢數據後,Django會將查詢集快取起來,並返回請求的結果,再次查詢相同數據時將重用快取的結果。

限制查詢集

  • 查詢集返回列表,可以使用下標的方式進行限制,等同於sql中的limitoffset語句
  • 注意:不支援負數索引
  • 使用下標後返回一個新的查詢集,不會立即執行查詢
  • 如果獲取一個對象,直接使用[0],等同於[0:1].get()

    • 但是如果沒有數據,[0]引發IndexError異常,[0:1].get()引發DoesNotExist異常

基礎條件查詢

  查詢語法

filter(模型屬性__條件運算符=值)  例:  filter(name__contains='')

  說明:查詢語句是屬性名稱和比較運算符間使用兩個下劃線相連,所以定義的模型屬性名不能包括多個下劃線

  實現sql中where的功能,可以調用過濾器filter()、exclude()、get()

  查詢需求

# 1.查詢id為1的書籍  # 2.查詢書名包含‘時間’的書籍  # 3.查詢書名以‘觀’結尾的書籍  # 4.查詢書名不為空的書籍  # 5.查詢價格為50或52的書籍  # 6.查詢價格大於52的書籍  # 7.查詢id不等於3的書籍  # 8.查詢2019年發表的書籍  # 9.查詢2000年1月1日後發表的書籍

  查詢實現

1.查詢id為1的書籍(exact:判斷相等)
 #1、查詢id為1的書籍(exact: 判斷相等)<QuerySet [<Books: 與時間做朋友>]>
   book = Books.objects.all()
book1 = book.filter(id__exact=1)

2.查詢書名包含‘時間’的書籍(contains:是否包含)
    book = Books.objects.all()      book1 = book.filter(name__contains="局觀")

#<QuerySet [<Books: 大局觀>]>


3.查詢書名以‘與’開始的書籍(startswith,endswith)
 book = Books.objects.all()      book1 = book.filter(name__startswith="")      print(book1)

 4.查詢書名不為空的書籍(isnull:是否為null)
 book = Books.objects.all()      book1 = book.filter(name__isnull=False)      print(book1)

5.查詢價格為50或52的書籍(in:是否包含在這範圍內)
 book = Books.objects.all()      book1 = book.filter(price__in=[50,52])      print(book1)

6.查詢價格大於52的書籍(gt,gte,it,ite:大於,大於等於,小於,小於等於)
    book = Books.objects.all()      book1 = book.filter(price__gt=52)      print(book1)


 7.查詢id不等於3的書籍(exclude:條件以外的數據)
   book = Books.objects.all()      book1 = book.exclude(id=3)      print(book1)

 8.查詢2019年發表的書籍(yearmonthdayweek_dayhourminutesecond:對日期時間類型的屬性進行運算)
    book = Books.objects.all()      book1 = book.filter(pub_data__year=2019)      print(book1)

 9.查詢2000年1月1日後發表的書籍
   from datetime import date      book = Books.objects.all()      book1 = book.filter(pub_data__gt=date(2000,1,1))      print(book1)

備註:

  • exactcontainsstartswithendswith運算符都區分大小寫
  • 在這些運算符前加上i表示不區分大小寫
    • iexacticontainsistartswithiendswith

 

其他特殊查詢下一節分享總結(F和Q查詢,聚合函數,關聯查詢)