web後端--Django學習筆記03
一:ORM(Object Relationship Mapping)
ORM:物件關係(關係型資料庫)對映。程式中的模型類對映到 關係型資料庫中的一個表,模型類的例項化物件對映到 資料表中的一條記錄。 操作模型類中的物件,就可以對應於表中的記錄。
二:模型類
Django中的模型類需要繼承Model類(django.db.models.Model), 模型類屬性對應於表字段。 例如:建立Product模型類 class Product(models.Model): proname = models.CharField(max_length=20) price = models.FloatField()
模型建立完成後,需要遷移,遷移需要兩步:
1.製作遷移計劃
python manage.py makemigrations
2.執行遷移任務
python manage.py migrate
三:控制檯操作Model
1. 進入控制檯
python manage.py shell 注意:這種進入控制檯的方式的搜尋路徑包含了當前專案
2插入表記錄
方式一:通過模型類的物件管理器插入記錄 p1 = Product.objects.create(proname='洗衣機',price=208.5)
方式二:例項化模型物件,並save() p2 = Product(proname='電視機',price=5000) p2.save()
3.查詢記錄
查詢單條記錄product = Product.objects.get(id=1) # get方法只能返回一條記錄,否則報錯
查詢所有記錄products = Product.objects.all()注意:all()方法查詢出的物件是一個QuerySet型別的物件,該物件可以被遍歷。
4.過濾查詢
使用物件管理器的filter()方法進行過濾查詢articles = Article.objects.filter(pub_date=date.today())對應的SQL為:select * from articles where pub_date='2018-09-19'
欄位後面跟雙下劃線"__",表示特殊查詢articles = Article.objects.filter(pub_date__year='2001')注:查詢的是年份為2001年的文章
articles = Article.objects.filter(pub_date__gte='2000-01-01')注:查詢的是日期大於等於2000-01-01。
常用的雙下劃線魔法引數有:
__year __month __startswith __gte __lte __contains (相當於模糊查詢)
articles = Article.objects.exclude(pub_date__month='8') 注:exclude()方法排除指定條件的記錄
5.限制查詢
articles = Article.objects.all()[:2] # 查詢前兩條記錄articles = Article.objects.all()[1:3] # 查詢從索引為1(第二條記錄)到索引為2的記錄articles = Article.objects.all()[:3:2] # 從索引為0開始查詢,結束索引為2,步幅為2
6.排序查詢
articles = Article.objects.order_by("pub_date") # 按照pub_date欄位升序排序
articles = Article.objects.order_by("-pub_date") # 按照pub_date欄位降序排序
還可以對排序後的結果進行切片,或取得某個物件article = Article.objects.order_by("-pub_date")[0] # 降序排序後,取第一個模型物件
articles = Article.objects.order_by("-pub_date")[:2] # 降序後,取前兩個物件,儲存於QuerySet中
四:原生SQL查詢
原生模糊查詢
articles = Article.objects.raw("select * from articles where title like '%%o%%'")
在原生SQL中使用佔位符articles = Article.objects.raw("select * from articles where title='%s'"%'good day')如果SQL中有多個佔位符:articles = Article.objects.raw("select * from articles where title='%s' or title='%s'"%('good day','ordinary day'))
articles = Article.objects.raw("select * from articles where title=%s",['good day'])如果SQL中有多個佔位符:articles = Article.objects.raw("select * from articles where title=%s or title=%s",['good day','bad day'])
五:Q查詢
對於複雜組合查詢條件,使用Q查詢很方便。 Q查詢依賴於Q物件(from django.db.models import Q) 通過例項化Q物件,將Q物件傳遞到filter()、get()方法中可以組合出多種查詢條件。 Q物件之間可以使用&、|。在Q物件前加~表示Q封裝條件的否定條件。
例一:查詢21世紀的文章,並且title中包含字母'o'。q1 = Q(pub_date__gte='2000-01-01')q2 = Q(title__contains='o')articles = Article.objects.filter(q1&q2)
例二:q1與q2先進行或,然後再與title欄位的條件進行and操作。articles = Article.objects.filter(q1|q2,title__contains='o')
例三:查詢非q1條件的記錄articles = Article.objects.filter(~q1)
六:自定義物件管理器
自定義物件管理器繼承Manager類(from django.db.models import Manager) 在自定義管理器中實現自己的方法
class CakeManager(Manager): # 自定義物件管理器 def create_cake(self,name,price,color): cake = self.model() cake.name = name cake.price = price cake.color = color cake.save() return cake
class Cake(models.Model): name = models.CharField(max_length=20) price = models.FloatField() color = models.CharField(max_length=20) cakemanager = CakeManager() # 關聯自定義物件管理器
七、附錄
1、python終端程式碼
C:\python\DjangoDay3>python manage.py shell #進入控制檯,可載入當前專案
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import sys
>>> sys.path #當前路徑
['C:\\python\\DjangoDay3', 'C:\\python37\\python37.zip', 'C:\\pyt
hon37\\DLLs', 'C:\\python37\\lib', 'C:\\python37', 'C:\\python37\
\lib\\site-packages']
>>> from myapp.models import * #匯入模型
>>> p1 = Product.objects.create(proname='洗衣機',price=208.5) #新增記錄
>>> p2 = Product.objects.create(proname='電視機',price=508.5)
>>> products = Product.objects.all()
>>> products = Product.objects.all()
>>> p1.price=300
>>> p1.save
<bound method Model.save of <Product: Product object (2)>>
>>> p1.save()
>>> p3 =Product(proname ='冰箱',price = 5000) #例項化物件新增記錄
>>> p3.save()# 儲存上面記錄
>>> product = Product.objects.get(id=1) #查詢id為1的記錄
>>> product.proname
'洗衣機'
>>> p3.proname
'冰箱'
>>> product = Product.objects.get(id=3) #獲取id 為3的記錄
>>> product.price #呼叫屬性
508.5
>>> products =Product.objects.all() #獲取所有記錄
>>> type(products) #檢視型別
<class 'django.db.models.query.QuerySet'>
>>> for p in products: #遍歷查詢到的所有記錄
... print(p.proname)
...
洗衣機
洗衣機
電視機
冰箱
>>> p1.proname #呼叫類屬性
'洗衣機'
>>> p2.proname
'電視機'
>>> p1.proname ='電扇' 呼叫類屬性並更改記錄
>>> p1.save() #儲存上面更改的記錄
>>> for p in products: #遍歷 資料表中的記錄
... print(p.proname)
...
洗衣機
洗衣機
電視機
冰箱
>>> products = Product.objects.exclude(proname='電視機') 查詢除電視機以外的記錄
>>> for p in products:
... print(p.proname) #遍歷查詢到的記錄
...
洗衣機
電扇
冰箱
>>> products = Product.objects.filter(proname='電視機') #過濾查詢
>>> for p in products:
... print(p.proname)
...
電視機
>>>
2、MySQL程式碼
[email protected]:~$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.23-0ubuntu0.16.04.1 (Ubuntu)
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use mydb
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables
-> ;
+----------------------------+
| Tables_in_mydb |
+----------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
| myapp_product |
+----------------------------+
11 rows in set (0.00 sec)
mysql> select * from myapp_product;
+----+-----------+-------+
| id | proname | price |
+----+-----------+-------+
| 1 | 洗衣機 | 208 |
+----+-----------+-------+
1 row in set (0.00 sec)
mysql> select * from myapp_product;
+----+-----------+-------+
| id | proname | price |
+----+-----------+-------+
| 1 | 洗衣機 | 208 |
| 2 | 洗衣機 | 208.5 |
| 3 | 電視機 | 508.5 |
+----+-----------+-------+
3 rows in set (0.00 sec)
mysql> select * from myapp_product;
+----+-----------+-------+
| id | proname | price |
+----+-----------+-------+
| 1 | 洗衣機 | 208 |
| 2 | 洗衣機 | 208.5 |
| 3 | 電視機 | 508.5 |
+----+-----------+-------+
3 rows in set (0.00 sec)
mysql> select * from myapp_product;
+----+-----------+-------+
| id | proname | price |
+----+-----------+-------+
| 1 | 洗衣機 | 208 |
| 2 | 洗衣機 | 208.5 |
| 3 | 電視機 | 508.5 |
+----+-----------+-------+
3 rows in set (0.00 sec)
mysql> select * from myapp_product;
+----+-----------+-------+
| id | proname | price |
+----+-----------+-------+
| 1 | 洗衣機 | 208 |
| 2 | 洗衣機 | 208.5 |
| 3 | 電視機 | 508.5 |
+----+-----------+-------+
3 rows in set (0.00 sec)
mysql> select * from myapp_product;
+----+-----------+-------+
| id | proname | price |
+----+-----------+-------+
| 1 | 洗衣機 | 208 |
| 2 | 洗衣機 | 300 |
| 3 | 電視機 | 508.5 |
+----+-----------+-------+
3 rows in set (0.00 sec)
mysql> select * from myapp_product;
+----+-----------+-------+
| id | proname | price |
+----+-----------+-------+
| 1 | 洗衣機 | 208 |
| 2 | 洗衣機 | 300 |
| 3 | 電視機 | 508.5 |
| 4 | 冰箱 | 5000 |
+----+-----------+-------+
4 rows in set (0.00 sec)
mysql> select * from myapp_product;
+----+-----------+-------+
| id | proname | price |
+----+-----------+-------+
| 1 | 洗衣機 | 208 |
| 2 | 電扇 | 300 |
| 3 | 電視機 | 508.5 |
| 4 | 冰箱 | 5000 |
+----+-----------+-------+
4 rows in set (0.00 sec)
mysql>
3、python終端程式碼
python manage.py shell#進入控制檯
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914
64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more informati
on.
(InteractiveConsole)
>>> from myapp.models import * #匯入模型
>>> Article.objects.create(title='bad day',content='糟糕的一天',pub 插入記錄
_dae ='1998-10-10')
<Article: Article object (2)>
>>> from datetime import date #匯入模組
>>> Article.objects.create(title='nice day',content='good的一天',pu
b_dae =date.today())
<Article: Article object (3)>
>>> Article.objects.create(title='nice day',content='good的一天',pu
b_dae =date(2015,12,21))
<Article: Article object (4)>
>>> article =Article.objects.get(id=3)
>>> articles = Article.objects.filter(pub_dae=date.today())
>>> len(articles) #檢視查詢到的記錄個數
1
>>> articles = Article.objects.filter(pub_dae__year='1988') #魔法方法 查詢出版年份為1988年
>>> articles[0]
<Article: Article object (1)>
>>> articles[0].title
'good day'
C:\python\DjangoDay3>python manage.py shell #進入控制檯
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914
64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more informati
on.
(InteractiveConsole)
>>> from datetime import date
>>> articles =Article.objects.filter(title__startswith='b') #魔法方法,查詢標題以b開頭的記錄
>>> articles[0].title
'bad day'
>>>
>>> articles =Article.objects.filter(title__contains='a') #魔法方法,查詢標題中包含a字母的所有記錄
>>> len(articles) #檢視查詢到記錄的個數
4
>>> articles =Article.objects.filter(pub_dae__gte='2001-01-01') #魔法方法,查詢2001-01-01之後的記錄/gte表示大於等於。
>>> len(articles)#檢視查詢到記錄的個數
2
>>> articles[0].pub_dae #檢視查詢到的第一條記錄
datetime.date(2018, 10, 8)
>>> articles[1].pub_dae #檢視查詢到的第二條記錄
datetime.date(2015, 12, 21)
>>>
>>> articles =Article.objects.filter(pub_dae__lte='2001-01-01') #查詢2001-01-01之前的記錄, lte表示小於等於
>>> articles[1].pub_dae #檢視查詢到的記錄
datetime.date(1998, 10, 10)
>>> articles =Article.objects.all()[:2] #切片查詢 0到1兩條記錄
>>> articles[1].title
'bad day'
>>> articles =Article.objects.all()[:3:2] #切片查詢,0到2中步頻為2的記錄
>>> articles[1].title
'nice day'
>>> articles[0].title
'good day'
>>> articles =Article.objects.all()[1:3] #切片查詢1到2的記錄
>>> articles[0].title
'bad day'
>>> articles =Article.objects.order_by("pub_dae") #以pub_dae欄位,排序查詢(預設升序)
>>> for a in articles:
... print(a.title) #遍歷
...
good day
bad day
nice day
nice day
>>> for a in articles:
... print(a.pub_dae)
...
1988-08-08
1998-10-10
2015-12-21
2018-10-08
>>> articles =Article.objects.order_by("-pub_dae")#以pub_dae欄位,排序查詢,降序。
>>> for a in articles:
... print(a.pub_dae) #遍歷
...
2018-10-08
2015-12-21
1998-10-10
1988-08-08
>>> articles =Article.objects.order_by("pub_dae")[:3]
>>> for a in articles:
... print(a.pub_dae)
...
1988-08-08
1998-10-10
2015-12-21
#原生MySQL語句查詢
>>> articles =Article.objects.raw("select * from articles") #查詢所有記錄
>>> type(articles)
<class 'django.db.models.query.RawQuerySet'>
>>> for a in articles: #遍歷
... print(a.title)
...
good day
bad day
nice day
nice day
>>> articles =Article.objects.raw("select * from article
s where title like '%%o%%'") 模糊查詢,查詢標題中含有字母o的記錄
>>> for a in articles:
... print(a.title)
...
good day
>>> articles =Article.objects.raw("select * from article
s where title=%s",['good day']) #模糊查詢,佔位%S 查詢title為good dayd的記錄
>>> for a in articles:
... print(a.title) 遍歷
...
good day
>>> articles =Article.objects.raw("select * from article
s where title=%s or title= %s",['good day','bad day'])#模糊查詢,佔位%S 查詢title為good dayd 或bad day的記錄.
>>> for a in articles:
... print(a.title)
...
good day
bad day
>>> type(articles) #檢視資料型別
<class 'django.db.models.query.RawQuerySet'>
#Q查詢
>>> from django.db.models import Q #匯入模組Q
>>> q = Q(title__contains='o') #查詢title中包含字母o的記錄
>>> articles =Article.objects.filter(q)
>>> for a in articles:
... print(a.title)
...
good day
>>> q1 =Q(pub_dae__gte='2000-01-01') #查詢時間大於等於2000-01-01的記錄
>>> q2 = Q(title__contains='o') #查詢title中包含字母o的記錄
>>> articles =Article.objects.filter(q1|q2) #查詢滿足q1或q2的記錄
>>> for a in articles:
... print(a.title)
...
good day
nice day
nice day
>>> articles =Article.objects.filter(q1&q2) ##查詢滿足q1或q2的記錄
>>> for a in articles:
... print(a.title)
...
>>> articles =Article.objects.filter(~q1) #查詢不滿足q1的記錄
>>> for a in articles:
... print(a.title)
...
good day
bad day
>>>
# manager應用終端
C:\python\DjangoDay3>python manage.py startapp managerapp #建立應用
C:\python\DjangoDay3>python manage.py makemigrations managerapp 遷移計劃日誌
Migrations for 'managerapp':
managerapp\migrations\0001_initial.py
- Create model Cake
C:\python\DjangoDay3>python manage.py migrate #遷移到資料庫
Operations to perform:
Apply all migrations: admin, auth, contenttypes, managerapp, myapp, sessions
Running migrations:
Applying managerapp.0001_initial... OK
C:\python\DjangoDay3>python manage.py shell 啟動控制檯
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.19
14 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more informa
tion.
(InteractiveConsole)
>>> from managerapp.models import * #匯入模型
>>> Cake.cakemanager.create_cake('生日蛋糕',20.5,'黃色')
>>> Cake.cakemanager.create_cake('祝賀蛋糕',100,'紅色' )
>>> cakes = Cake.cakemanager.query_cake() #查詢所有記錄
>>> type(cakes)
<class 'django.db.models.query.QuerySet'>
>>> for i in cakes:
... print(i.name)
...
生日蛋糕
祝賀蛋糕
祝賀蛋糕
>>> for i in cakes:
... print(i)
...
生日蛋糕
祝賀蛋糕
祝賀蛋糕
>>>
4、python Django下myapp應用中模型類程式碼
# models 檔案
from django.db import models
from django.db.models import Manager
class CakeManager(Manager):#自定義物件管理器
def create_cake(self,name,price,color):
cake = self.model()
cake.name =name
cake.price = price
cake.color = color
cake.save()
def query_cake(self): #類方法
return super().all()
class Cake(models.Model):
name = models.CharField(max_length=20)
price = models.FloatField()
color = models.CharField(max_length=20)
cakemanager =CakeManager() #關聯自定義物件管理器
def __str__(self):
return self.name
class Meta:
db_table ='cakes'
5、python Django下managerappp應用中模型類程式碼
#models檔案
from django.db import models
class Product(models.Model):
proname = models.CharField(max_length=20)
price = models.FloatField()
class Article(models.Model):
title = models.CharField(max_length=20) #標題
content = models.TextField()# 內容,型別
pub_dae = models.DateField()#發表日期
class Meta:
db_table ='articles'#自定義模型對應名稱