1. 程式人生 > >web後端--Django學習筆記03

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'#自定義模型對應名稱