Django模型層之單表操做

Django模型層之單表操做

一 、ORM簡介

undefined

咱們在使用Django框架開發web應用的過程當中,不可避免地會涉及到數據的管理操做(如增、刪、改、查),而一旦談到數據的管理操做,就須要用到數據庫管理軟件,例如mysqloracleMicrosoft SQL Server等。python

若是應用程序須要操做數據(好比將用戶註冊信息永久存放起來),那麼咱們須要在應用程序中編寫原生sql語句,而後使用pymysql模塊遠程操做mysql數據庫,詳見圖一^①^mysql

可是直接編寫原生sql語句會存在兩方面的問題,嚴重影響開發效率,以下git

  • sql語句的執行效率:應用開發程序員須要耗費一大部分精力去優化sql語句
  • 數據庫遷移:針對mysql開發的sql語句沒法直接應用到oracle數據庫上,一旦須要遷移數據庫,便須要考慮跨平臺問題

爲了解決上述問題,django引入了ORM的概念,ORM全稱Object Relational Mapping,即對象關係映射,是在pymysq之上又進行了一層封裝,對於數據的操做,咱們無需再去編寫原生sql,取代代之的是基於面向對象的思想去編寫類、對象、調用相應的方法等,ORM會將其轉換/映射成原生SQL而後交給pymysql執行,詳見圖二^②^程序員

undefined

圖片一

undefined

圖片二

如此,開發人員既不用再去考慮原生SQL的優化問題,也不用考慮數據庫遷移的問題,ORM都幫咱們作了優化且支持多種數據庫,這極大地提高了咱們的開發效率,下面就讓咱們來詳細學習ORM的使用吧web

undefined

二 、單表操做

2.1 按步驟建立表

2.1.1 models.py

建立django項目,新建名爲app01app,在app01models.py中建立模型sql

class Employee(models.Model): # 必須是models.Model的子類
    id=models.AutoField(primary_key=True)

    name=models.CharField(max_length=16)

    gender=models.BooleanField(default=1)

    birth=models.DateField()

    department=models.CharField(max_length=30)

    salary=models.DecimalField(max_digits=10,decimal_places=1)

2.1.2 settings.py

django的`orm支持多種數據庫,若是想將上述模型轉爲mysql數據庫中的表,須要settings.py數據庫

# 刪除\註釋掉原來的DATABASES配置項,新增下述配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # 使用mysql數據庫
        'NAME': 'db1',          # 要鏈接的數據庫
        'USER': 'root',         # 連接數據庫的用於名
        'PASSWORD': '',         # 連接數據庫的用於名                  
        'HOST': '127.0.0.1',    # mysql服務監聽的ip  
        'PORT': 3306,           # mysql服務監聽的端口  
        'ATOMIC_REQUEST': True, #設置爲True表明同一個http請求所對應的全部sql都放在一個事務中執行 
                                #(要麼全部都成功,要麼全部都失敗),這是全局性的配置,若是要對某個
                                #http請求放水(而後自定義事務),能夠用non_atomic_requests修飾器 
        'OPTIONS': {
            "init_command": "SET storage_engine=INNODB", #設置建立表的存儲引擎爲INNODB
        }
    }
}

2.1.3 創建數據庫

在鏈接mysql數據庫前,必須事先建立好數據庫django

mysql> create database db1; # 數據庫名必須與settings.py中指定的名字對應上

2.1.4 插曲

其實python解釋器在運行django程序時,djangoorm底層操做數據庫的python模塊默認是mysqldb而非pymysql,然而對於解釋器而言,python2.x解釋器支持的操做數據庫的模塊是mysqldb,而python3.x解釋器支持的操做數據庫的模塊則是pymysql,,毫無疑問,目前咱們的django程序都是運行於python3.x解釋器下,因而咱們須要修改djangoorm默認操做數據庫的模塊爲pymysql,具體作法以下python3.x

undefined

2.1.5 註冊

確保配置文件settings.py中的INSTALLED_APPS中添加咱們建立的app名稱,django2.xdjango1.x處理添加方式不一樣api

# django1.x版本,在下述列表中新增咱們的app名字便可
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01',
    # 'app02' # 如有新增的app,依次添加便可
]

# django2.x版本,可能會幫咱們自動添加app,只是換了一種添加方式
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config', # 若是默認已經添加了,則無需重複添加
    # 'app02.apps.App02Config', # 如有新增的app,按照規律依次添加便可
]

2.1.6 日誌的配置

若是想打印orm轉換過程當中的sql,須要在settings中進行配置日誌:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

2.1.7 數據庫遷移

最後在命令行中執行兩條數據庫遷移命令,便可在指定的數據庫db1中建立表 :

$ python manage.py makemigrations
$ python manage.py migrate

# 注意:
# 一、makemigrations只是生成一個數據庫遷移記錄的文件,而migrate纔是將更改真正提交到數據庫執行
# 二、數據庫遷移記錄的文件存放於app01下的migrations文件夾裏
# 三、瞭解:使用命令python manage.py showmigrations能夠查看沒有執行migrate的文件

注意1:在使用的是django1.x版本時,若是報以下錯誤

django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None

那是由於MySQLclient目前只支持到python3.4,若是使用的更高版本的python,須要找到文件C:\Programs\Python\Python36-32\Lib\site-packages\Django-2.0-py3.6.egg\django\db\backends\mysql
這個路徑裏的文件

# 註釋下述兩行內容便可
if version < (1, 3, 3):
     raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)

注意2:當咱們直接去數據庫裏查看生成的表時,會發現數據庫中的表與orm規定的並不一致,這徹底是正常的,事實上,orm的字段約束就是不會所有體如今數據庫的表中,好比咱們爲字段gender設置的默認值default=1,去數據庫中查看會發現該字段的default部分爲null

mysql> desc app01_employee; # 數據庫中標籤前會帶有前綴app01_
+------------+---------------+------+-----+---------+----------------+
| Field      | Type          | Null | Key | Default | Extra          |
+------------+---------------+------+-----+---------+----------------+
| id         | int(11)       | NO   | PRI | NULL    | auto_increment |
| name       | varchar(16)   | NO   |     | NULL    |                |
| gender     | tinyint(1)    | NO   |     | NULL    |                |
| birth      | date          | NO   |     | NULL    |                |
| department | varchar(30)   | NO   |     | NULL    |                |
| salary     | decimal(10,1) | NO   |     | NULL    |                |
+------------+---------------+------+-----+---------+----------------+

雖然數據庫沒有增長默認值,可是咱們在使用orm插入值時,徹底爲gender字段插入空,orm會按照本身的約束將空轉換成默認值後,再提交給數據庫執行

2.1.8 數據庫之表的操做

在表生成以後,若是須要增長、刪除、修改表中字段,須要這麼作

# 一:增長字段
# 1.一、在模型類Employee裏直接新增字段,強調:對於orm來講,新增的字段必須用default指定默認值
publish = models.CharField(max_length=12,default='人民出版社',null=True)

#1.二、從新執行那兩條數據庫遷移命令

# 二:刪除字段
# 2.1 直接註釋掉字段
# 2.2 從新執行那兩條數據庫遷移命令

# 三:修改字段
# 3.1 將模型類中字段修改
# 3.2 從新執行那兩條數據庫遷移命令

2.2 添加記錄

  • 方式一:
# 一、用模型類建立一個對象,一個對象對應數據庫表中的一條記錄
obj = Employee(name="Egon", gender=0, birth='1997-01-27', department="財務部", salary=100.1)
# 二、調用對象下的save方法,便可以將一條記錄插入數據庫
obj.save()
  • 方式二:
# 每一個模型表下都有一個objects管理器,用於對該表中的記錄進行增刪改查操做,其中增長操做以下所示
obj = Employee.objects.create(name="Egon", gender=0, birth='1997-01-27', department="財務部", salary=100.1)

2.3 查詢記錄

2.3.1 查詢API

模型Employee對應表app01_employee,表app01_employee中的每條記錄都對應類Employee的一個對象,咱們以該表爲例,來介紹查詢API,讀者能夠自行添加下述記錄,而後配置url、編寫視圖測試下述API

mysql> select * from app01_employee;
+----+-------+--------+------------+------------+--------+
| id | name  | gender | birth      | department | salary |
+----+-------+--------+------------+------------+--------+
|  1 | Egon  |      0 | 1997-01-27 | 財務部     |  100.1 |
|  2 | Kevin |      1 | 1998-02-27 | 技術部     |   10.1 |
|  3 | Lili  |      0 | 1990-02-27 | 運營部     |   20.1 |
|  4 | Tom   |      1 | 1991-02-27 | 運營部     |   30.1 |
|  5 | Jack  |      1 | 1992-02-27 | 技術部     |   11.2 |
|  6 | Robin |      1 | 1988-02-27 | 技術部     |  200.3 |
|  7 | Rose  |      0 | 1989-02-27 | 財務部     |   35.1 |
|  8 | Egon  |      0 | 1997-01-27 | 財務部     |  100.1 |
|  9 | Egon  |      0 | 1997-01-27 | 財務部     |  100.1 |
+----+-------+--------+------------+------------+--------+

每一個模型表下都有一個objects管理器,用於對該表中的記錄進行增刪改查操做,其中查詢操做以下所示

undefined

  • Part1

!!!強調!!!下述方法(除了count外)的返回值都是一個模型類Employee的對象,爲了後續描述方便,咱們統一將模型類的對象稱爲「記錄對象」,每個」記錄對象「都惟一對應表中的一條記錄,

# 1. get(**kwargs)
# 1.1: 有參,參數爲篩選條件
# 1.2: 返回值爲一個符合篩選條件的記錄對象(有且只有一個),若是符合篩選條件的對象超過一個或者沒有都會拋出錯誤。
obj=Employee.objects.get(id=1)
print(obj.name,obj.birth,obj.salary) #輸出:Egon 1997-01-27 100.1

# 二、first()
# 2.1:無參
# 2.2:返回查詢出的第一個記錄對象
obj=Employee.objects.first() # 在表全部記錄中取第一個
print(obj.id,obj.name) # 輸出:1 Egon

# 三、last()
# 3.1: 無參
# 3.2: 返回查詢出的最後一個記錄對象
obj = Employee.objects.last() # 在表全部記錄中取最後一個
print(obj.id, obj.name)  # 輸出:9 Egon

# 四、count():
# 4.1:無參
# 4.2:返回包含記錄對象的總數量
res = Employee.objects.count() # 統計表全部記錄的個數
print(res) # 輸出:9

# 注意:若是咱們直接打印Employee的對象將沒有任何有用的提示信息,咱們能夠在模型類中定義__str__來進行定製
class Employee(models.Model):
    ......
    # 在原有的基礎上新增代碼以下
    def __str__(self):
        return "<%s:%s>" %(self.id,self.name)
# 此時咱們print(obj)顯示的結果就是: <本條記錄中id字段的值:本條記錄中name字段的值>

undefined

  • Part2

!!!強調!!!下述方法查詢的結果都有可能包含多個記錄對象,爲了存放查詢出的多個記錄對象,djangoORM自定義了一種數據類型Queryeset,因此下述方法的返回值均爲QuerySet類型的對象,QuerySet對象中包含了查詢出的多個記錄對象

# 一、filter(**kwargs):
# 1.1:有參,參數爲過濾條件
# 1.2:返回值爲QuerySet對象,QuerySet對象中包含了符合過濾條件的多個記錄對象
queryset_res=Employee.objects.filter(department='技術部')
# print(queryset_res) # 輸出: <QuerySet [<Employee: <2:Kevin>>, <Employee: <5:Jack>>, <Employee: <6:Robin>>]>

# 二、exclude(**kwargs)
# 2.1: 有參,參數爲過濾條件
# 2.2: 返回值爲QuerySet對象,QuerySet對象中包含了不符合過濾條件的多個記錄對象
queryset_res=Employee.objects.exclude(department='技術部')

# 三、all()
# 3.1:無參
# 3.2:返回值爲QuerySet對象,QuerySet對象中包含了查詢出的全部記錄對象
queryset_res = Employee.objects.all() # 查詢出表中全部的記錄對象

# 四、order_by(*field):
# 4.1:有參,參數爲排序字段,能夠指定多個字段,在字段1相同的狀況下,能夠按照字段2進行排序,以此類推,默認升序排列,在字段前加橫杆表明降序排(如"-id")
# 4.2:返回值爲QuerySet對象,QuerySet對象中包含了排序好的記錄對象
queryset_res = Employee.objects.order_by("salary","-id") # 先按照salary字段升序排,若是salary相同則按照id字段降序排

# 五、values(*field)
# 5.1:有參,參數爲字段名,能夠指定多個字段
# 5.2:返回值爲QuerySet對象,QuerySet對象中包含的並非一個個的記錄對象,而上多個字典,字典的key即咱們傳入的字段名
queryset_res = Employee.objects.values('id','name')
print(queryset_res) # 輸出:<QuerySet [{'id': 1, 'name': 'Egon'}, {'id': 2, 'name': 'Kevin'}, ......]>
print(queryset_res[0]['name']) # 輸出:Egon

# 六、values_list(*field):
# 6.1:有參,參數爲字段名,能夠指定多個字段
# 6.2:返回值爲QuerySet對象,QuerySet對象中包含的並非一個個的記錄對象,而上多個小元組,字典的key即咱們傳入的字段名
queryset_res = Employee.objects.values_list('id','name')
print(queryset_res) # 輸出:<QuerySet [(1, 'Egon'), (2, 'Kevin'),), ......]>
print(queryset_res[0][1]) # 輸出:Egon
  • Part3

<u>Part2中所示查詢API的返回值都是QuerySet類型的對象,QuerySet類型是django ORM自定義的一種數據類型,專門用來存放查詢出的多個記錄對象,該類型的特殊之處在於

  1. queryset類型相似於python中的列表,支持索引操做
# 過濾出符合條件的多個記錄對象,而後存放到QuerySet對象中
queryset_res=Employee.objects.filter(department='技術部') 
# 按照索引從QuerySet對象中取出第一個記錄對象
obj=queryset_res[0]
print(obj.name,obj.birth,obj.salary)
  1. 管理器objects下的方法queryset下一樣能夠調用,而且djangoORM支持鏈式操做,因而咱們能夠像下面這樣使用
# 簡單示範:
res=Employee.objects.filter(gender=1).order_by('-id').values_list('id','name')
print(res) # 輸出:<QuerySet [(6, 'Robin'), (5, 'Jack'), (4, 'Tom'), (2, 'Kevin')]>
  • Part4

其餘查詢API

# 一、reverse():
# 1.1:無參
# 1.2:對排序的結果取反,返回值爲QuerySet對象
queryset_res = Employee.objects.order_by("salary", "-id").reverse()

# 二、exists():
# 2.1:無參
# 2.2:返回值爲布爾值,若是QuerySet包含數據,就返回True,不然返回False
res = Employee.objects.filter(id=100).exists()
print(res)  # 輸出:False

# 三、distinct():
# 3.1:若是使用的是Mysql數據庫,那麼distinct()無需傳入任何參數
# 3.2:從values或values_list的返回結果中剔除重複的記錄對象,返回值爲QuerySet對象
res = Employee.objects.filter(name='Egon').values('name', 'salary').distinct()
print(res) # 輸出:<QuerySet [{'name': 'Egon', 'salary': Decimal('100.1')}]>

res1 = Employee.objects.filter(name='Egon').values_list('name', 'salary').distinct()
print(res1) # 輸出:<QuerySet [('Egon', Decimal('100.1'))]>

2.3.2 基於雙下劃線的模糊查詢

undefined

2.3.3 FQ查詢

2.3.3.1F查詢

在上面全部的例子中,咱們在進行條件過濾時,都只是用某個字段與某個具體的值作比較。若是咱們要對兩個字段的值作比較,那該怎麼作呢?

Django提供 F() 來作這樣的比較。F() 的實例能夠在查詢中引用字段,來比較兩個不一樣字段的值,以下

# 一張書籍表中包含字段:評論數commentNum、收藏數keepNum,要求查詢:評論數大於收藏數的書籍
from django.db.models import F
Book.objects.filter(commnetNum__lt=F('keepNum'))

Django 支持 F() 對象之間以及F()對象和常數之間的加減乘除和取模的操做

# 查詢評論數大於收藏數2倍的書籍
from django.db.models import F
Book.objects.filter(commnetNum__lt=F('keepNum')*2)

修改操做也可使用F函數,好比將每一本書的價格提升30元:

Book.objects.all().update(price=F("price")+30) 

undefined

filter() 等方法中逗號分隔開的多個關鍵字參數都是邏輯與(AND)的關係。 若是咱們須要使用邏輯或(OR)來鏈接多個條件,就用到了DjangoQ對象

能夠將條件傳給類Q來實例化出一個對象,Q的對象可使用&| 操做符組合起來,&等同於and|等同於or

from django.db.models import Q
Employee.objects.filter(Q(id__gt=5) | Q(name="Egon"))

# 等同於sql:select * from app01_employee where id < 5 or name = 'Egon';
2.3.3.2 Q查詢

Q 對象可使用~ 操做符取反,至關於NOT

from django.db.models import Q
Employee.objects.filter(~Q(id__gt=5) | Q(name="Egon"))

# 等同於sql:select * from app01_employee where not (id < 5) or name = 'Egon';

當咱們的過濾條件中既有or又有and,則須要混用Q對象與關鍵字參數,但Q 對象必須位於全部關鍵字參數的前面

from django.db.models import Q
Employee.objects.filter(Q(id__gt=5) | Q(name="Egon"),salary__lt=100)

# 等同於sql:select * from app01_employee where (id < 5 or name = 'Egon') and salary < 100;

undefined

2.3.4 聚合查詢

聚合查詢aggregate()是把全部查詢出的記錄對象總體當作一個組,咱們能夠搭配聚合函數來對總體進行一個聚合操做

from django.db.models import Avg, Max, Sum, Min, Max, Count # 導入聚合函數

# 1. 調用objects下的aggregate()方法,會把表中全部記錄對象總體當作一組進行聚合
res1=Employee.objects.aggregate(Avg("salary")) # select avg(salary) as salary__avg from app01_employee;
print(res1) # 輸出:{'salary__avg': 70.73}

# 二、aggregate()會把QuerySet對象中包含的全部記錄對象當成一組進行聚合
res2=Employee.objects.all().aggregate(Avg("salary")) # select avg(salary) as salary__avg from app01_employee;
print(res2) # 輸出:{'salary__avg': 70.73}

res3=Employee.objects.filter(id__gt=3).aggregate(Avg("salary")) # select avg(salary) as salary__avg from app01_employee where id > 3;
print(res3) # 輸出:{'salary__avg': 71.0}

aggregate()的返回值爲字典類型,字典的key是由聚合字段的名稱___聚合函數的名稱合成的,例如

Avg("salary") 合成的名字爲 'salary__avg'

若咱們想定製字典的key名,咱們能夠指定關鍵參數,以下

res1=Employee.objects.all().aggregate(avg_sal=Avg('salary')) # select avg(salary) as avg_sal from app01_employee;

print(res1) # 輸出:{'avg_sal': 70.73} # 關鍵字參數名就會被當作字典的key

若是咱們想獲得多個聚合結果,那就須要爲aggregate傳入多個參數

res1=Employee.objects.all().aggregate(nums=Count('id'),avg_sal=Avg('salary'),max_sal=Max('salary')) 
# 至關於SQL:select count(id) as nums,avg(salary) as avg_sal,max(salary) as max_sal from app01_employee;

print(res1) # 輸出:{'nums': 10, 'avg_sal': 70.73, 'max_sal': Decimal('200.3')}

2.3.5 分組查詢

分組查詢annotate()至關於sql語句中的group by,是在分組後,對每一個組進行單獨的聚合,須要強調的是,在進行單表查詢時,annotate()必須搭配values()使用:values(「分組字段」).annotate(聚合函數),以下

# 表中記錄
mysql> select * from app01_employee;
+----+-------+--------+------------+------------+--------+
| id | name  | gender | birth      | department | salary |
+----+-------+--------+------------+------------+--------+
|  1 | Egon  |      0 | 1997-01-27 | 財務部     |  100.1 |
|  2 | Kevin |      1 | 1998-02-27 | 技術部     |   10.1 |
|  3 | Lili  |      0 | 1990-02-27 | 運營部     |   20.1 |
|  4 | Tom   |      1 | 1991-02-27 | 運營部     |   30.1 |
|  5 | Jack  |      1 | 1992-02-27 | 技術部     |   11.2 |
|  6 | Robin |      1 | 1988-02-27 | 技術部     |  200.3 |
|  7 | Rose  |      0 | 1989-02-27 | 財務部     |   35.1 |
+----+-------+--------+------------+------------+--------+

# 查詢每一個部門下的員工數
res=Employee.objects.values('department').annotate(num=Count('id')) 
# 至關於sql:
# select department,count(id) as num from app01_employee group by department;

print(res) 
# 輸出:<QuerySet [{'department': '財務部', 'num': 2}, {'department': '技術部', 'num': 3}, {'department': '運營部', 'num': 2}]>

跟在annotate前的values方法,是用來指定分組字段,即group by後的字段,而跟在annotate後的values方法,則是用來指定分組後要查詢的字段,即select 後跟的字段

res=Employee.objects.values('department').annotate(num=Count('id')).values('num')
# 至關於sql:
# select count(id) as num from app01_employee group by department;

print(res)
# 輸出:<QuerySet [{'num': 2}, {'num': 3}, {'num': 2}]>

跟在annotate前的filter方法表示where條件,跟在annotate後的filter方法表示having條件,以下

# 查詢男員工數超過2人的部門名
res=Employee.objects.filter(gender=1).values('department').annotate(male_count=Count("id")).filter(male_count__gt=2).values('department')

print(res) # 輸出:<QuerySet [{'department': '技術部'}]>

# 解析:
# 一、跟在annotate前的filter(gender=1) 至關於 where gender = 1,先過濾出全部男員工信息
# 二、values('department').annotate(male_count=Count("id")) 至關於group by department,對過濾出的男員工按照部門分組,而後聚合出每一個部門內的男員工數賦值給字段male_count
# 三、跟在annotate後的filter(male_count__gt=2) 至關於 having male_count > 2,會過濾出男員工數超過2人的部門
# 四、最後的values('department')表明從最終的結果中只取部門名

總結

一、values()在annotate()前表示group by的字段,在後表示取值
一、filter()在annotate()前表示where條件,在後表示having

須要注意的是,若是咱們在annotate前沒有指定values(),那默認用表中的id字段做爲分組依據,而id各不相同,如此分組是沒有意義的,以下

res=Employee.objects.annotate(Count('name'))  # 每條記錄都是一個分組
res=Employee.objects.all().annotate(Count('name'))  # 同上

2.4 修改記錄

2.4.1 直接修改單條記錄

能夠修改記錄對象屬性的值,而後執行save方法從而完成對單條記錄的直接修改

# 一、獲取記錄對象
obj=Employee.objects.filter(name='Egon')[0]
# 二、修改記錄對象屬性的值
obj.name='EGON'
obj.gender=1
# 三、從新保存
obj.save()

2.4.2 修改QuerySet中的全部記錄對象

QuerySet對象下的update()方法能夠更QuerySet中包含的全部對象,該方法會返回一個整型數值,表示受影響的記錄條數(至關於sql語句執行結果的rows

queryset_obj=Employee.objects.filter(id__gt=5)
rows=queryset_obj.update(name='EGON',gender=1)

2.5 刪除記錄

undefined

2.5.1 直接刪除單條記錄

能夠直接調用記錄對象下的delete方法,該方法運行時當即刪除本條記錄而不返回任何值,以下

obj=Employee.objects.first()
obj.delete()

2.5.2 刪除QuerySet中的全部記錄對象

每一個 QuerySet下也都有一個 delete()方法,它一次性刪除 QuerySet中全部的對象(若是QuerySet對象中只有一個記錄對象,那也就只刪一條),以下

queryset_obj=Employee.objects.filter(id__gt=5)
rows=queryset_obj.delete()

須要強調的是管理objects下並無delete方法,這是一種保護機制,是爲了不意外地調用 Employee.objects.delete() 方法致使全部的記錄被誤刪除從而跑路。但若是你確認要刪除全部的記錄,那麼你必須顯式地調用管理器下的all方法,拿到一個QuerySet對象後才能調用delete方法刪除全部

Employee.objects.all().delete()

undefined

相關文章
相關標籤/搜索