中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python的Django框架怎么實現數據庫查詢

發布時間:2020-07-23 14:54:06 來源:億速云 閱讀:262 作者:小豬 欄目:開發技術

小編這次要給大家分享的是Python的Django框架怎么實現數據庫查詢,文章內容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。

一、創建模型類:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
class Course(models.Model):
 """課程表"""
 name = models.CharField(verbose_name='課程名稱', max_length=255)
 description = models.TextField(verbose_name='課程描述信息', null=True)
 price = models.DecimalField(verbose_name=u'課程價格', max_digits=15, decimal_places=2, default=0.0)
 deleted = models.BooleanField(verbose_name='課程是否被刪除', default=False)
	created_at = models.DateTimeField(auto_now_add=True, db_index=True)
 edited_at = models.DateTimeField(auto_now=True)

 def __repr__(self):
 return self.name

class User(models.Model):
 """用戶表:記錄用戶常用信息"""
 name = models.CharField(verbose_name=u'用戶的姓名', max_length=32, null=True)
 mobile = models.CharField(verbose_name=u'用戶的手機號', max_length=32, unique=True)
 courses = models.ManyToManyField(verbose_name=u'關聯課程', to='Course', through='UserCourse', related_name='user_course')

class UserExtra(models.Model):
 """用戶信息額外表: 存儲一些用戶不常用信息"""
 birthday = models.CharField(verbose_name=u'生日', max_length=32, null=True)
 email = models.EmailField(verbose_name=u'郵箱', null=True)
 user = models.OneToOneField(to=User, related_name='extra') # 跟User表是一對一的關系

class UserCourse(models.Model):
 """課程表跟用戶表手動添加的多對多表"""
 course = models.ForeignKey('Course', related_name='my_course')
 user = models.ForeignKey('User', related_name='my_user')

class Coursechapter(models.Model):
 """課程章節表"""
 name = models.CharField(verbose_name='課程名稱', max_length=255)
 description = models.TextField(verbose_name='課程描述信息', null=True)
 course = models.ForeignKey('Course', related_name='course_chapter')

執行以下命令,進行數據庫的遷移:

python manage.py makemigrations app_name[應用的名稱]
python manage.py migrate app_name[應用的名稱]

遷移成功后可以進行以下的操作咯~

二、介紹不返回QuerySet的方法:

方法名介紹
get()獲取單個對象
create()創建對象
bulk_create()批量創建對象
get_or_create()查詢對象,若沒有找到則創建新的對象
update()批量更新對象
update_or_create()更新對象,若沒有找到則創建新的對象
delete()批量刪除對象
first()獲取第一個對象
last()獲取最后一個對象
latest()獲取最近的對象
earliest()獲取最早的對象
count()統計對象的個數
exists()判斷queryset中是否有對象
aggregate()聚合操作
in_bulk()根據主鍵值的列表,批量返回對象
iterator()獲取包含對象的迭代器

三、以上方法的使用:

1.get()方法:

返回按照查詢參數匹配到的單個對象,若匹配到的對象個數不只一個的話,會觸發MultipleObjectsReturned異常,若根據參數匹配不到對象的時候,會觸發DoesNotExist異常。

成功栗子:

try:
 user_obj = models.User.objects.get(mobile=13069636688)
 print(user_obj)
except models.User.DoesNotExist:
 print 'User Not Exist'
# 輸出結果:
User object 

使用get()方法最好將異常捕獲添加上。

獲取參數失敗栗子:

# 使用get()方法獲取一條不存在的數據
user_obj = models.User.objects.get(mobile=13888888888)
# 拋出異常:
DoesNotExist: User matching query does not exist.

# 使用get()方法獲取多條數據
user_obj = models.User.objects.get(name='小明')
# 拋出異常:
MultipleObjectsReturned: get() returned more than one User -- it returned 2!

使用ObjectDoesNotExist異常栗子:

DoesNotExist異常從django.core.exceptions.ObjectDoesNotExist繼承,可以定位多個DoesNotExist異常,舉個栗子:

from django.core.exceptions import ObjectDoesNotExist
try:
 user_obj = models.User.objects.get(mobile=13888888888)
except ObjectDoesNotExist:
 print 'User Not Exist'
# 拋出自定義異常:
User Not Exist

通常我們使用get()方法中的參數,都是查詢表中作為唯一標識的字段。

2.create()方法:

create(**kwargs)

在一步操作中同時創建并且保存對象的便捷方法。

舉個栗子:

user_obj = models.User.objects.create(mobile=13045621111, name='小牛')
print(user_obj)
# 輸出結果如果:
User object

同等于:

user_obj = models.User(mobile=13045621112, name='小牛')
user_obj.save()

3.bulk_create()方法:

bulk_create(objs, batch_size=None)

這種插入比較高效(通常僅一個查詢,無論有多少對象),將提供的對象列表插入到數據庫中。

舉個栗子:

course_obj = models.Course.objects.bulk_create(
 [
 models.Course(name='哈爾濱工業大學'),
 models.Course(name='長春大學')
 ]
)
print course_obj
# 輸出結果如下:
[<Course: 哈爾濱工業大學>, <Course: 長春大學>]

注意:

1.不會調用模型的save()方法,所以不會發送pre_save和post_save信號。

2.不適用多張表繼承中的子模型。

3.不適用于多對多關系。

4. get_or_create() 方法:

get_or_create(defaults=None, **kwargs)

通過kwargs來查詢對象的簡便方法(若模型中所有字段都有默認值或可以為空),如果該對象不存在則創建一個新的對象。

該方法返回一個由(object,created)組成的元組,元組中的object是一個查詢到或被創建的對象,created是一個表示是否創建新對象的布爾值(true:表示創建新對象|false:相反)。

舉個栗子:

try:
 # 通過id=100查看課程是否存在
 course_obj = models.Course.objects.get(pk=100)
except ObjectDoesNotExist:
 # 如果不存在就創建一門課程
 course_obj = models.Course.objects.create(name='上海財經大學', price='1877')

使用get_or_create()方法重寫的栗子:

# 查看課程的name="上海交通大學", 如果不存在, 那么創建一條name="信息科技大學",price=2000的數據
obj, created = models.Course.objects\
 .get_or_create(name='上海交通大學',
  defaults={'name': '信息科技大學', 'price': 2000})

print(obj, created)
# 輸出結果如下:
Course object True

注意:

&#8203; 1.任何傳遞給get_or_create()的關鍵字參數,除了一個可選的defaults,都將傳遞給get()方法調用。

&#8203; 2.如果找到一個對象,返回一個包含匹配到的對象以及False組成元組。

&#8203; 3.如果查到的對象超過一個以上,將拋出MultipleObjectsReturned異常。

&#8203; 4.如果找不到對象,get_or_create()將會實例化并保存一個新的對象,返回一個由新的對象以及True組成元組。

建議:只在Django視圖的POST請求中使用get_or_create(),因為這是一個具有修改性質的動作,不應該使用在GET請求中,那樣不安全。

5. update()方法:

update(**kwargs)

對指定的字段執行批量更新操作,并返回匹配的行數

舉個栗子:

# 可以更新多個字段,沒有多少字段的限制
course_row = models.Course.objects.filter(name='北京大學')\
 .update(name='上海交通大學', price=2000)

print(course_row)
# 輸出結果如下:
1 # 表示僅在數據庫中修改了一條數據

注意:

&#8203; 1.update()方法無需save()操作,唯一限制是它只能更新模型主表中的列,而不是關聯的整個模型。

&#8203; 2.update()方法返回受影響的行數。

&#8203; 3.update()方法還可以防止在加載對象和調用save()之間的短時間內數據庫中某些內容可能發生更改的競爭條件。

僅是更新一下對象,不需要為對象做其他事情,最有效的方法是調用update(),而不是將模型對象加載到內存中去。

# 不要這么做的栗子:
course_obj = models.Course.objects.get(name='北京大學')
course_obj.name = '北京大學'
course_obj.save()

6.update_or_create()方法:

update_or_create(defaults=None, **kwargs)

通過給出的kwargs來更新對象的便捷方法, 如果沒找到對象,則創建一個新的對象。

defaults是一個由 (field, value)對組成的字典,用于更新對象。defaults中的值可以是可調用對象。

該方法返回一個由(object, created)組成的元組,元組中的object是一個創建的或者是被更新的對象, created是一個標示是否創建了新的對象的布爾值(true(表示創建成功)|false(相反)) 。

舉個栗子:

try:
 # 查看課程name="北京大學"存在,若存在那么將name修改成"財經大學"進行保存
 course_obj = models.Course.objects.get(name='北京大學')
 course_obj.name = '財經大學'
 course_obj.save()
except ObjectDoesNotExist:
 # 如果不存在, 則創建一條name="北京大學"的課程
 course_obj = models.Course.objects.create(name='北京大學')

使用update_or_create()方法重寫:

# 查找課程name="財經大學"是否存在, 如果存在,將name跟price字段進行更新, 若不存在創建新的記錄
obj, res = models.Course.objects\
 .update_or_create(name='財經大學',
  defaults={'name': '復旦大學', 'price': 2080})

print(obj, res)
# 輸出結果:
Course object False # 表示沒有創建新的對象, 若找到該對象將更新

Course object True # 表示創建了新的對象

7.delete()方法:

delete()

批量刪除QuerySet中的所有對象,并返回刪除的對象個數和每個對象類型的刪除次數的字典。
delete()動作是立即執行的。

舉個栗子:

# 刪除課程price=2080的所有課程
cur_course =models.Course.objects.filter(price=2080).delete()
print(cur_course)

# 輸出結果:
(7, {u'apps.Coursechapter': 2, u'apps.Course': 2, u'apps.UserCourse': 3})
# 分析以上結果, 7表示共刪除7條數據, Coursechapter表中2條數據, Course表中2條數據, UserCourse表中3條數據

注意:delete()會為所有已刪除的對象(包括級聯刪除、對象的外鍵、多對多的關系)發出pre_delete和post_delete信號。

8.first()方法:

first()

返回結果集的第一個對象, 當沒有找到時返回None。如果QuerySet沒有設置排序,則將會自動按主鍵進行排序。

舉個栗子:

# 獲取課程表所有數據中的第一條數據
course_obj = models.Course.objects.all().first()
print(course_obj)
# 輸出結果如下:
Course object # 說明獲取到了第一條數據

# 獲取課程name='農業大學'的第一條數據
course_obj = models.Course.objects.filter(name='農業大學').first()
print(course_obj)
# 輸出結果:
None # 說明課程表中沒有name='農業大學'

使用[0]來獲取第一個對象:

course_obj = models.Course.objects.filter(name='農業大學')[0]
print(course_obj)
# 輸出結果:
IndexError: list index out of range # 拋出異常,沒有找到并不會返回None

# 如果使用[0]方法,需要添加異常處理
try:
 course_obj = models.Course.objects.filter(name='農業大學')[0]
except IndexError:
 course_obj = None

9.last()方法:

last()

跟first()方法相同,只是返回的是查詢集中最后一個對象。

舉個栗子:

# 獲取課程表中最后一條數據
course_obj = models.Course.objects.last()
print(course_obj)
# 輸出結果:
Course object

10.latest()方法:

latest(field_name=None)

使用日期字典field_name,按日期返回最新對象。

舉個栗子:

# 查看按創建課程日前返回的最新對象
course_obj = models.Course.objects.filter(created_at__isnull=False).latest('created_at')
print(course_obj.id)
# 輸出結果:
101 # 這次是打印的Course表的ID,因為創建課程時, 這就是創建的最新對象。

注意:earliest()和latest()可能會返回空日期的實例,可能需要過濾掉空值 。

11.earliest()方法:

earliest(field_name=None)

跟latest()方法相同,只是返回查詢集中按日期最早的對象。

舉個栗子:

# 獲取課程表中按日期創建課程最早的對象
course_obj = models.Course.objects.filter(created_at__isnull=False).earliest('created_at')
print(course_obj.id)
# 輸出結果:
1 # 打印Course表中的ID,因為數據庫第一條數據,就是最早創建的

12.count()方法:

count()

返回在數據庫中對應的QuerySet對象的個數。

舉個栗子:

course_count = models.Course.objects.all().count()
print(course_count)
# 輸出結果:

count()永遠不會引發異常。

13.exists()方法:

exists()

如果QuerySet包含任何結果,則返回True,否則返回False。

舉個栗子:

# 查找課程表中是否包含name="信息科技大學的集合"
course_list = models.Course.objects.filter(name='信息科技大學')
# 如果存在就打印"存在"
if course_list.exists():
 print('存在')
# 輸出結果:
存在

該exists()方法快于以下栗子:

# 同樣查找課程中是否包含name="信息科技大學"
course_list = models.Course.objects.filter(name='信息科技大學')
if course_list:
 print('存在')
# 輸出結果:
存在

14.aggregate()方法:

aggregate(args, *kwargs)

返回匯總值的字典(平均值、總和等),通過QuerySet進行計算,每個參數指定返回的字典中將要包含的值。

舉個栗子:

匿名參數的名稱將基于聚合函數的名稱和模型字段生成

from django.db.models import Count

# 獲取課程名稱name="信息科技大學",將"name"字段進行聚合統計
course_dict = models.Course.objects.filter(name="信息科技大學").aggregate(Count('name'))
print(course_dict)
# 輸出結果:
{u'name__count': 3} # 將基于聚合函數的名稱(count)和模型字段(name)生成 

再舉個栗子:

使用關鍵字參數來指定聚合函數,可以控制返回的聚合的值的名稱。

from django.db.models import Count

# 獲取課程名稱name="信息科技大學", 將name字段進行聚合統計
course_dict = models.Course.objects.filter(name="信息科技大學")\
 .aggregate(customize_name=Count('name'))
print(course_dict)
# 輸出結果:
{'customize_name': 3} # 使用關鍵字參數指定聚合函數,返回聚合的值名稱

15.in_bulk()方法:


in_bulk(id_list=None)

獲取主鍵值的列表,并返回將每個主鍵值映射到具有給定ID的對象的實例的字典。如果未提供列表,則會返回查詢集中所有對象。

舉個栗子:

# 獲取課程表中ID是1的對象
course_obj = models.Course.objects.in_bulk([1])
print(course_obj)
# 輸出結果:
{1: <Course: Course object>}

# 獲取課程表中ID是2,3的對象
course_obj = models.Course.objects.in_bulk([2, 3])
print(course_obj)
# 輸出結果:
{2: <Course: Course object>, 3: <Course: Course object>}

# 若列表中沒有填寫ID, 返回空字典
course_obj = models.Course.objects.in_bulk([])
print(course_obj)
# 輸出結果:
{}

# 獲取課程表所有的ID對應的對象, 返回一個字典
course_obj = models.Course.objects.in_bulk()
print(course_obj)
# 輸出結果:
{1: <Course: Course object>, 2: <Course: Course object>, 3: <Course: Course object>, 4: <Course: Course object>, 5: <Course: Course object>, 6: <Course: Course object>,

16.iterator()方法:

iterator()

提交數據庫操作,獲取QuerySet,返回一個迭代器。

QuerySet通常會再內部緩存其結果,以便再重復計算時不會導致額外的查詢。

主要時QuerySet的緩存機制,如果一次從數據庫取出很多數據,就有可能導致程序崩潰,可以利用iterator()方法,做性能優化。

舉個栗子:

# 取出數據庫的所有對象, 要考慮cache機制, 如果數據量太大, 程序就會崩潰
course_list = models.Course.objects.all()

# 利用iterator()方法, 這次就不能用2次for循環, 第一次for循環, 就已經遍歷完了
course_set = models.Course.objects.all().iterator()
print(next(course_set))
print(next(course_set))
print(next(course_set))

# 對數據庫進行更新, 但并沒有執行, 只有再用的時候再執行
models.Course.objects.filter(pk=1).update(price=66)


# 如果for循環2次, 打印2次結果, 也是執行一次sql語句,因為存在sql緩存機制,
# 把第一次查詢的結果放到緩存里, 下次從緩存里調
for obj in course_list:
 print(obj.name, obj.price)

"""
# 更新數據之前
id:1
name: 上海交通大學
price: 2000
# 更新數據后
id:1 
name: 上海交通大學
price : 66
"""

使用iterator()會導致先前的prefetch_related()調用被忽略,因為這兩個一起優化沒有意義。

看完這篇關于Python的Django框架怎么實現數據庫查詢的文章,如果覺得文章內容寫得不錯的話,可以把它分享出去給更多人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宽城| 施秉县| 潼关县| 汨罗市| 崇州市| 普格县| 神木县| 凤山县| 宜兰市| 永城市| 建平县| 井研县| 东乡县| 景宁| 永州市| 屏东县| 泰兴市| 犍为县| 株洲市| 弥渡县| 广平县| 新河县| 巴彦县| 瑞昌市| 驻马店市| 三门峡市| 澄迈县| 镇沅| 泾源县| 东莞市| 隆安县| 项城市| 龙江县| 洛南县| 文登市| 东光县| 景东| 从化市| 乐亭县| 花垣县| 奎屯市|