日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

ORM操作

發(fā)布時(shí)間:2025/7/25 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ORM操作 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

單表使用ORM對(duì)數(shù)據(jù)庫(kù)的增刪改查

ORM與數(shù)據(jù)庫(kù)的對(duì)應(yīng)

類?   ?==>  表

對(duì)象  ? ==>  記錄

屬性  ==>  字段

from django.db import modelsclass Publisher(models.Model):id = models.AutoField(primary_key=True)name = models.CharField(max_length=32, unique=True)class Book(models.Model):id = models.AutoField(primary_key=True)title = models.CharField(max_length=32, unique=True)publisher = models.ForeignKey(to=Publisher, on_delete=models.CASCADE)# publisher為外鍵,ORM自動(dòng)將publisher后面加上_id作為字段傳給數(shù)據(jù)庫(kù),可以使用book_obj.publisher_id找到書(shū)籍對(duì)象對(duì)應(yīng)的出版社的id,這是直接操作數(shù)據(jù)庫(kù)的# publisher作為ORM中BOOK類的屬性,可以通過(guò)book_obj.publisher找到書(shū)籍對(duì)象對(duì)應(yīng)的出版社對(duì)象,這仍然是通過(guò)ORM操作數(shù)據(jù)庫(kù)def __repr__(self):return "<Book object: {} >".format(self.title)class Author(models.Model):name = models.CharField(max_length=32, unique=True)books = models.ManyToManyField('Book')def __repr__(self):return "<Author object: {} >".format(self.name)__str__ = __repr__增:普通表: models.Publisher.objects.create(name='xxx') 帶外鍵的表: models.Book.objects.create(name='xxx',publisher=publisher_obj)models.Book.objects.create(name='xxx',publisher_id=publisher_obj.id)帶多對(duì)多的表: author_obj = models.Author.objects.create(name='xxxxx')author_obj.books.set([1,3,4])刪除:對(duì)象列表.delete()對(duì)象.delete()修改:普通表: pub_obj.name='xxxxx'pub_obj.save()帶外鍵的表: book_obj.title = 'xxxxx'book_obj.publisher = publisher_obj 或book_obj.publisher_id = publisher_obj.id 或 book_obj.publisher_id = 'id的數(shù)值'(推薦這種寫(xiě)法,直接操作數(shù)據(jù)庫(kù))book_obj.save()帶多對(duì)多的表 author_obj.name = 'xxx'author_obj.save() author_obj.books.set([1,3,4])查:普通字段: pub_obj.id外鍵字段: book_obj.publisher —— 》 關(guān)聯(lián)的出版社對(duì)象book_obj.publisher_id —— 》 關(guān)聯(lián)的出版社對(duì)象的id多對(duì)多字段: author_ob.books —— 》 管理對(duì)象 author_ob.books.all() —— 》 作者關(guān)聯(lián)的所有書(shū)籍對(duì)象列表

?

?


?

常用字段?

AutoField

自增的整形字段,必填參數(shù)primary_key=True,則成為數(shù)據(jù)庫(kù)的主鍵。無(wú)該字段時(shí),django自動(dòng)創(chuàng)建。

一個(gè)model不能有兩個(gè)AutoField字段。

IntegerField

一個(gè)整數(shù)類型。數(shù)值的范圍是?-2147483648 ~ 2147483647。

CharField

字符類型,必須提供max_length參數(shù)。max_length表示字符的長(zhǎng)度。

DateField

日期類型,日期格式為YYYY-MM-DD,相當(dāng)于Python中的datetime.date的實(shí)例。

參數(shù):

  • auto_now:每次修改時(shí)修改為當(dāng)前日期時(shí)間。
  • auto_now_add:新創(chuàng)建對(duì)象時(shí)自動(dòng)添加當(dāng)前日期時(shí)間。

auto_now和auto_now_add和default參數(shù)是互斥的,不能同時(shí)設(shè)置。

DatetimeField

?

復(fù)制代碼AutoField(Field)- int自增列,必須填入?yún)?shù) primary_key=TrueBigAutoField(AutoField)- bigint自增列,必須填入?yún)?shù) primary_key=True注:當(dāng)model中如果沒(méi)有自增列,則自動(dòng)會(huì)創(chuàng)建一個(gè)列名為id的列from django.db import modelsclass UserInfo(models.Model):# 自動(dòng)創(chuàng)建一個(gè)列名為id的且為自增的整數(shù)列username = models.CharField(max_length=32)class Group(models.Model):# 自定義自增列nid = models.AutoField(primary_key=True)name = models.CharField(max_length=32)SmallIntegerField(IntegerField):- 小整數(shù) -32768 ~ 32767PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)- 正小整數(shù) 0 ~ 32767IntegerField(Field)- 整數(shù)列(有符號(hào)的) -2147483648 ~ 2147483647PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)- 正整數(shù) 0 ~ 2147483647BigIntegerField(IntegerField):- 長(zhǎng)整型(有符號(hào)的) -9223372036854775808 ~ 9223372036854775807BooleanField(Field)- 布爾值類型NullBooleanField(Field):- 可以為空的布爾值CharField(Field)- 字符類型- 必須提供max_length參數(shù), max_length表示字符長(zhǎng)度TextField(Field)- 文本類型EmailField(CharField):- 字符串類型,Django Admin以及ModelForm中提供驗(yàn)證機(jī)制IPAddressField(Field)- 字符串類型,Django Admin以及ModelForm中提供驗(yàn)證 IPV4 機(jī)制GenericIPAddressField(Field)- 字符串類型,Django Admin以及ModelForm中提供驗(yàn)證 Ipv4和Ipv6- 參數(shù):protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"unpack_ipv4, 如果指定為True,則輸入::ffff:192.0.2.1時(shí)候,可解析為192.0.2.1,開(kāi)啟此功能,需要protocol="both"URLField(CharField)- 字符串類型,Django Admin以及ModelForm中提供驗(yàn)證 URLSlugField(CharField)- 字符串類型,Django Admin以及ModelForm中提供驗(yàn)證支持 字母、數(shù)字、下劃線、連接符(減號(hào))CommaSeparatedIntegerField(CharField)- 字符串類型,格式必須為逗號(hào)分割的數(shù)字UUIDField(Field)- 字符串類型,Django Admin以及ModelForm中提供對(duì)UUID格式的驗(yàn)證FilePathField(Field)- 字符串,Django Admin以及ModelForm中提供讀取文件夾下文件的功能- 參數(shù):path, 文件夾路徑match=None, 正則匹配recursive=False, 遞歸下面的文件夾allow_files=True, 允許文件allow_folders=False, 允許文件夾FileField(Field)- 字符串,路徑保存在數(shù)據(jù)庫(kù),文件上傳到指定目錄- 參數(shù):upload_to = "" 上傳文件的保存路徑storage = None 存儲(chǔ)組件,默認(rèn)django.core.files.storage.FileSystemStorageImageField(FileField)- 字符串,路徑保存在數(shù)據(jù)庫(kù),文件上傳到指定目錄- 參數(shù):upload_to = "" 上傳文件的保存路徑storage = None 存儲(chǔ)組件,默認(rèn)django.core.files.storage.FileSystemStoragewidth_field=None, 上傳圖片的高度保存的數(shù)據(jù)庫(kù)字段名(字符串)height_field=None 上傳圖片的寬度保存的數(shù)據(jù)庫(kù)字段名(字符串)DateTimeField(DateField)- 日期+時(shí)間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]DateField(DateTimeCheckMixin, Field)- 日期格式 YYYY-MM-DDTimeField(DateTimeCheckMixin, Field)- 時(shí)間格式 HH:MM[:ss[.uuuuuu]]DurationField(Field)- 長(zhǎng)整數(shù),時(shí)間間隔,數(shù)據(jù)庫(kù)中按照bigint存儲(chǔ),ORM中獲取的值為datetime.timedelta類型FloatField(Field)- 浮點(diǎn)型DecimalField(Field)- 10進(jìn)制小數(shù)- 參數(shù):max_digits,小數(shù)總長(zhǎng)度decimal_places,小數(shù)位長(zhǎng)度BinaryField(Field)- 二進(jìn)制類型 詳細(xì)字段類型

?

#自定義一個(gè)char類型字段: class MyCharField(models.Field):"""自定義的char類型的字段類"""def __init__(self, max_length, *args, **kwargs):self.max_length = max_lengthsuper(MyCharField, self).__init__(max_length=max_length, *args, **kwargs)def db_type(self, connection):"""限定生成數(shù)據(jù)庫(kù)表的字段類型為char,長(zhǎng)度為max_length指定的值"""return 'char(%s)' % self.max_length #使用自定義char類型字段: class Class(models.Model):id = models.AutoField(primary_key=True)title = models.CharField(max_length=25)# 使用自定義的char類型的字段cname = MyCharField(max_length=25)

?

?

null 數(shù)據(jù)庫(kù)中字段是否可以為空db_column 數(shù)據(jù)庫(kù)中字段的列名default 數(shù)據(jù)庫(kù)中字段的默認(rèn)值primary_key 數(shù)據(jù)庫(kù)中字段是否為主鍵db_index 數(shù)據(jù)庫(kù)中字段是否可以建立索引unique 數(shù)據(jù)庫(kù)中字段是否可以建立唯一索引unique_for_date 數(shù)據(jù)庫(kù)中字段【日期】部分是否可以建立唯一索引unique_for_month 數(shù)據(jù)庫(kù)中字段【月】部分是否可以建立唯一索引unique_for_year 數(shù)據(jù)庫(kù)中字段【年】部分是否可以建立唯一索引verbose_name Admin中顯示的字段名稱blank Admin中是否允許用戶輸入為空editable Admin中是否可以編輯help_text Admin中該字段的提示信息choices Admin中顯示選擇框的內(nèi)容,用不變動(dòng)的數(shù)據(jù)放在內(nèi)存中從而避免跨表操作如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)error_messages 自定義錯(cuò)誤信息(字典類型),從而定制想要顯示的錯(cuò)誤信息;字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date如:{'null': "不能為空.", 'invalid': '格式錯(cuò)誤'}validators 自定義錯(cuò)誤驗(yàn)證(列表類型),從而定制想要的驗(yàn)證規(guī)則from django.core.validators import RegexValidatorfrom django.core.validators import EmailValidator,URLValidator,DecimalValidator,\MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator如:test = models.CharField(max_length=32,error_messages={'c1': '優(yōu)先錯(cuò)信息1','c2': '優(yōu)先錯(cuò)信息2','c3': '優(yōu)先錯(cuò)信息3',},validators=[RegexValidator(regex='root_\d+', message='錯(cuò)誤了', code='c1'),RegexValidator(regex='root_112233\d+', message='又錯(cuò)誤了', code='c2'),EmailValidator(message='又錯(cuò)誤了', code='c3'), ])字段參數(shù) 字段參數(shù)

Model Meta參數(shù)

app01 下的models.py
class
UserInfo(models.Model):nid = models.AutoField(primary_key=True)username = models.CharField(max_length=32)class Meta:# 數(shù)據(jù)庫(kù)中生成的表名稱 默認(rèn) app名稱 + 下劃線 + 類名db_table = "table_name"# admin中顯示的表名稱verbose_name = '個(gè)人信息'# verbose_name加sverbose_name_plural = '所有用戶信息'# 聯(lián)合索引 index_together = [("pub_date", "deadline"), # 應(yīng)為兩個(gè)存在的字段 ]# 聯(lián)合唯一索引unique_together = (("driver", "restaurant"),) # 應(yīng)為兩個(gè)存在的字段

普通索引:僅加速查詢

唯一索引:加速查詢 + 列值唯一(可以有null)

主鍵索引:加速查詢 + 列值唯一 + 表中只有一個(gè)(不可以有null)

組合索引:多列值組成一個(gè)索引,
? ? ? ? ? ? ? 專門用于組合搜索,其效率大于索引合并

全文索引:對(duì)文本的內(nèi)容進(jìn)行分詞,進(jìn)行搜索?


查詢的13條命令?

不必非在app下的models進(jìn)行ORM操作,可以在項(xiàng)目目錄下新建文件夾,新建py文件進(jìn)行ORM操作

我們?cè)赿jango中運(yùn)行項(xiàng)目都是通過(guò)manage.py來(lái)完成的,下面的代碼設(shè)置的一些環(huán)境在manage.py中也有,可以直接粘過(guò)來(lái)

import osif __name__ == '__main__':os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_practice.settings") # orm_practice是當(dāng)前的項(xiàng)目名import djangodjango.setup()from app01 import models# all 獲取所有對(duì)象 ——》 QuerySetret = models.Person.objects.all()# get 獲取單獨(dú)的對(duì)象 ——》 對(duì)象# 找不到或者找到多個(gè)就報(bào)錯(cuò)ret= models.Person.objects.get(id=1,name='阿旭')# filter 過(guò)濾 獲取所有滿足條件的對(duì)象 ——》QuerySetret = models.Person.objects.filter(id=1)# exclude 獲取不滿足條件的所有對(duì)象ret = models.Person.objects.exclude(id=1)# values ——》QuerySet 元素是字典# 不寫(xiě)參數(shù) 默認(rèn)所有字段的名字和值# 寫(xiě)參數(shù) 拿到指定字段的名字和值ret = models.Person.objects.all().values('id','name')ret = models.Person.objects.values('id','name')# values_list ——》QuerySet 元素是元組 只有值沒(méi)有字段名# 不寫(xiě)參數(shù) 默認(rèn)所有字段值# 寫(xiě)參數(shù) 拿到指定字段值ret = models.Person.objects.values_list('name','id')# print(ret)# for i in ret :# print(i,type(i))# reverse 對(duì)已經(jīng)排序的QuerySet進(jìn)行反轉(zhuǎn)ret = models.Person.objects.all().reverse()# distinct 去重 ——》QuerySet# count 對(duì)QuerySet中的元素進(jìn)行計(jì)數(shù)ret = models.Person.objects.filter(id=100).count()# first 取QuerySet中的第一個(gè)元素ret = models.Person.objects.all().first()# last 取QuerySet中的最后一個(gè)元素ret = models.Person.objects.all().last()ret = models.Person.objects.values_list().last()ret = models.Person.objects.filter(id=100).first()# exists 判斷查詢結(jié)果是否有值ret = models.Person.objects.filter(id=100).exists()# print(ret)# order_by 按字段進(jìn)行排序 ——》QuerySetret =models.Person.objects.order_by('age')print(ret) """ 返回是QuerySet的方法 1. all() 2. filter() 3. values() 4. values_list() 5. order_by() 6. distinct() 7. reverse() 8. exclude()返回是對(duì)象 1. get() 2. first() 3. last()返回是布爾值 1. exists()返回是數(shù)字 1. count()"""

?

?


?單表的雙下劃線

import osif __name__ == '__main__':os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_practice.settings")import djangodjango.setup()from app01 import modelsret = models.Person.objects.filter(id__lt=3) # less thanret = models.Person.objects.filter(id__gt=3) # great than ret = models.Person.objects.filter(id__gte=3) # great than equelret = models.Person.objects.filter(id__lte=3) # great than equelret = models.Person.objects.filter(id__gte=3, id__lte=5)ret = models.Person.objects.exclude(id__gt=5)ret = models.Person.objects.filter(id__in=[1, 3, 5])ret = models.Person.objects.exclude(id__in=[1, 3, 5])ret = models.Person.objects.filter(id__gte=1, id__lte=100) #并且的關(guān)系ret = models.Person.objects.filter(id__range=[1, 5]) # id范圍在1-5包括1和5ret = models.Person.objects.filter(name__contains='A') # name包含'A'類似于sql語(yǔ)句中的likeret = models.Person.objects.filter(name__icontains='a') # name中包含'A'或'a',不區(qū)分大小寫(xiě) ret = models.Person.objects.filter(name__istartswith='a') # 以'a'開(kāi)頭ret = models.Person.objects.filter(name__endswith='x') # 以'x'結(jié)尾 ret = models.Person.objects.filter(birth__year='2018') # 篩選年份為'2018'日期的對(duì)象ret = models.Person.objects.filter(birth__month='09') # 篩選月份為'09'日期的對(duì)象ret = models.Person.objects.filter(name__isnull=True) # 篩選名字不為空的對(duì)象print(ret)

跨表查詢(連表查詢)中的雙下劃線表示另一個(gè)關(guān)聯(lián)表(外鍵關(guān)聯(lián)或多對(duì)多關(guān)聯(lián))中的字段.

如ret= models.Book.objects.filter(publisher__name='沙河出版社')? ??publisher__name表示publisher表中的name字段? ?這個(gè)語(yǔ)句的意思是篩選出所有 出版社為沙河出版社出版的書(shū)籍

import osif __name__ == '__main__':os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_practice.settings")import djangodjango.setup()from app01 import models# 正向查詢 book ——》 publisher# 基于對(duì)象查詢book_obj = models.Book.objects.get(id=1)print(book_obj.id)print(book_obj.title)print(book_obj.publisher_id)print(book_obj.publisher_id) # 關(guān)聯(lián)的出版社對(duì)象print(book_obj.publisher.id) # 關(guān)聯(lián)的出版社對(duì)象print(book_obj.publisher.name)# 基于字段查詢ret= models.Book.objects.filter(publisher__name='沙河出版社')ret= models.Book.objects.filter(publisher_id=1)print(ret)# 反向查詢 publisher ——》 book# 基于對(duì)象的查詢# 1 —— 》 多 表名小寫(xiě)_set ——》 管理對(duì)象 .all() 出版社關(guān)聯(lián)的所有書(shū)籍對(duì)象pub_obj = models.Publisher.objects.first()# 表名小寫(xiě)_set ,注意是表名小寫(xiě)_set 而不是子表(多對(duì)一中的多)的外鍵名_set ret = pub_obj.book_set.all() print(pub_obj.book_set,type(pub_obj.book_set)) book_set是外鍵反向查詢的管理對(duì)象print(ret)class Book(models.Model):title = models.CharField(max_length=32)publisher = models.ForeignKey('Publisher',related_name='books', # 關(guān)聯(lián)名字# related_query_name='xx', #關(guān)聯(lián)查詢名字on_delete=models.CASCADE, null=True)# Class Book中指定了related_name books# print(pub_obj.books.all())# 基于字段的查詢#1,不指定related_name和related_query_nameret = models.Publisher.objects.filter(book__title='跟太亮學(xué)開(kāi)車') 表名#2,指定related_name 不指定related_query_nameret = models.Publisher.objects.filter(books__title='跟太亮學(xué)開(kāi)車') 使用related_name 指定的名字 'books'#3,指定related_name和related_query_nameret = models.Publisher.objects.filter(xx__title='跟太亮學(xué)開(kāi)車') 使用related_query_name 指定的名字 'xx'print(ret)

?

import osif __name__ == '__main__':os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_practice.settings")import djangodjango.setup()from app01 import modelsauthor_obj = models.Author.objects.get(id=1)# print(author_obj.books.all()) books是多對(duì)多管理對(duì)象 # 多對(duì)多中的 creat() add() remove() clear()# create()# author_obj.books.create(title='戴綠與嫂子的故事',publisher_id=1)# 1. 創(chuàng)建書(shū)籍對(duì)象(與出版社進(jìn)行關(guān)聯(lián))# 2. 該對(duì)象和作者進(jìn)行關(guān)聯(lián)# add()book_list = models.Book.objects.filter(id__in=[1,6,8,9])author_obj.books.add(*books_list) # 增加作者對(duì)應(yīng)的書(shū)籍 可以寫(xiě)id 可以寫(xiě)對(duì)象,book_list是對(duì)象列表,需要用*打散# set()author_obj.books.set([1,6,8,9]) # 用書(shū)籍id設(shè)置作者對(duì)應(yīng)的書(shū)籍 author_obj.books.set(books)author_obj.books.remove(*books)author_obj.books.clear()# 一對(duì)多中的 creat() remove() clear()pub_obj= models.Publisher.objects.first()pub_obj.book_set book_set是反向查詢的管理對(duì)象pub_obj.books.create(title='跟老男孩學(xué)思想')pub_obj = models.Publisher.objects.get(id=1)# 一對(duì)多的管理對(duì)象remove不能使用id 使用對(duì)象pub_obj.books.remove(models.Book.objects.get(id=5))pub_obj.books.clear() # 清空關(guān)聯(lián)的書(shū)籍

聚合和分組

聚合:aggregate(*args,**kwargs)
  通過(guò)對(duì)QuerySet進(jìn)行計(jì)算,返回一個(gè)聚合值的字典。aggregate()中每一個(gè)參數(shù)都指定一個(gè)包含在字典中的返回值。即在查詢集上生成聚合。
  聚合的結(jié)果不包含原來(lái)表中的字段,aggregate()是QuerySet 的一個(gè)終止子句,只能在最后寫(xiě)他
分組:annotate(*args,**kwargs):
  可以通過(guò)計(jì)算查詢結(jié)果中每一個(gè)對(duì)象所關(guān)聯(lián)的對(duì)象集合,從而得出總計(jì)值(也可以是平均值或總和),即為查詢集的每一項(xiàng)生成聚合。
  對(duì)分組后的每一組進(jìn)行查詢計(jì)算,然后將結(jié)果作為注釋添加到表每行的數(shù)據(jù)中

簡(jiǎn)單看下用法,詳細(xì)用法見(jiàn)下面的練習(xí)代碼

#查詢alex出的書(shū)的總價(jià)格 Book.object.filter(authors__name='alex').aggregate(Sum('price')) #查詢各個(gè)作者出的書(shū)的總價(jià)格,這里就涉及到分組了,分組條件是anthors__name Book.object.values('authors__name').annotate(Sum('price')) #查詢各個(gè)出版社最便宜的書(shū)價(jià)是多少 Book.object.values('publisher__name').annotate(Min('price'))

F查詢和Q查詢

??

#僅僅靠單一的關(guān)鍵字參數(shù)查詢已經(jīng)很難滿足查詢要求。此時(shí)Django為我們提供了F查詢和Q查詢 # F 使用查詢條件的值,專門取對(duì)象中某列值的操作 models.Tb1.objects.update(num=F('num')+1) # 將num加1后重新賦值給num # Q 構(gòu)建搜索條件 models.Book.objects.filter(Q(id__lt=3)|Q(id__gt=5)).values() # filter中兩個(gè)條件以逗號(hào)分隔是and的關(guān)系,使用Q查詢可以有或的關(guān)系import os if __name__ == '__main__':os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_practice.settings")import djangodjango.setup()from app01 import modelsfrom django.db.models import F,Qret = models.Book.objects.filter(sale__gt=50).values() # 一個(gè)字段的比較不用使用F查詢r(jià)et = models.Book.objects.filter(sale__gte=F('kucun')+30).values() # 兩個(gè)字段的值進(jìn)行比較需要使用F查詢 ret = models.Book.objects.filter(~Q(id__lt=3)|Q(id__gt=5)).values() # ~是取反 和!意義一樣for i in ret:print(i)# updata()和save()的區(qū)別,updata只修改條件內(nèi)的表的字段,save是把所有的字段都再保存一遍# models.Book.objects.all().update(sale=100)# book_obj = models.Book.objects.get(id=1)# book_obj.sale=0# book_obj.save()# models.Book.objects.all().update(sale=(F('sale')+10)*2)

  詳細(xì)說(shuō)明

# F 使用查詢條件的值,專門取對(duì)象中某列值的操作from django.db.models import Fmodels.Tb1.objects.update(num=F('num')+1)# Q 構(gòu)建搜索條件from django.db.models import Q# 1 Q對(duì)象(django.db.models.Q)可以對(duì)關(guān)鍵字參數(shù)進(jìn)行封裝,從而更好地應(yīng)用多個(gè)查詢q1 = models.Book.objects.filter(Q(title__startswith='P')).all()print(q1) # [<Book: Python>, <Book: Perl>]# 2、可以組合使用&,|操作符,當(dāng)一個(gè)操作符是用于兩個(gè)Q的對(duì)象,它產(chǎn)生一個(gè)新的Q對(duì)象。Q(title__startswith='P') | Q(title__startswith='J')# 3、Q對(duì)象可以用~操作符放在前面表示否定,也可允許否定與不否定形式的組合Q(title__startswith='P') | ~Q(pub_date__year=2005)# 4、應(yīng)用范圍:# Each lookup function that takes keyword-arguments (e.g. filter(),# exclude(), get()) can also be passed one or more Q objects as# positional (not-named) arguments. If you provide multiple Q object# arguments to a lookup function, the arguments will be “AND”ed# together. For example:Book.objects.get(Q(title__startswith='P'),Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))# sql:# SELECT * from polls WHERE title LIKE 'P%'# AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')# import datetime# e=datetime.date(2005,5,6) #2005-05-06# 5、Q對(duì)象可以與關(guān)鍵字參數(shù)查詢一起使用,不過(guò)一定要把Q對(duì)象放在關(guān)鍵字參數(shù)查詢的前面。# 正確:Book.objects.get(Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),title__startswith='P')# 錯(cuò)誤:Book.objects.get(question__startswith='P',Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

事務(wù)

?通過(guò)事務(wù)我們可以把兩件或者兩件以上的ORM操作組成一個(gè)原子,這幾件事要么都成功,一旦有一個(gè)失敗了,那么全部不執(zhí)行,即使執(zhí)行過(guò)了也要回滾回去

比如,我們操作數(shù)據(jù)庫(kù)進(jìn)行轉(zhuǎn)賬操作,A向B轉(zhuǎn)賬分為兩步,A的賬戶扣錢,B的賬戶加錢,這兩件事必須都成功,或者都失敗

import osif __name__ == '__main__':os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_practice.settings")import djangodjango.setup()from app01 import modelstry:from django.db import transaction # 導(dǎo)入從django事務(wù)模塊import datetimewith transaction.atomic():new_publisher = models.Publisher.objects.create(name="火星出版社") # 這條語(yǔ)句單獨(dú)是可以成功的models.Book.objects.create(title="橘子物語(yǔ)",publisher_id=100) # 指定一個(gè)不存在的出版社id,這條語(yǔ)句會(huì)報(bào)錯(cuò),所以作為整體,事務(wù)內(nèi)所有語(yǔ)句都不會(huì)執(zhí)行except Exception as e:print(str(e))

  


ORM查詢練習(xí)

簡(jiǎn)單說(shuō)明:? ? publisher? ? ?字段? ?id? ? name? ?city

      book? ? ? ? ? ? 字段? ?id? ? title? ? publish_date? ? ?price? ? ?memo? ? ? publisher(外鍵關(guān)聯(lián)了publisher)? ? author(多對(duì)多管理對(duì)象,關(guān)聯(lián)了作者)

      author? ? ? ? ? 字段? ? id? ?name? ? age? ? ? phone

import osos.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_homework.settings") import djangodjango.setup()from app01 import models from django.db.models import Q, Max, Count# 查找所有書(shū)名里包含金老板的書(shū) ret = models.Book.objects.filter(title__contains='金老板')# 查找出版日期是2018年的書(shū) ret = models.Book.objects.filter(publish_date__year=2018)# 查找價(jià)格大于10元的書(shū) ret = models.Book.objects.filter(price__gt=10)# 查找memo字段是空的書(shū) # -----字段為空包括空字符串和null , null和空字符串并不是一回事 ret = models.Book.objects.filter(Q(memo='') | Q(memo__isnull=True))# 查找名字以沙河開(kāi)頭的出版社 # ----distinct去重,有兩個(gè)名字相同但是id不同的沙河出版社對(duì)象,所以這個(gè)去重并不能給對(duì)象去重,需要先使用values()取出出版社的名字,這樣變成字典后再對(duì)名字進(jìn)行去重 ret = models.Publisher.objects.filter(name__startswith='沙河').values('name').distinct()# 查找“沙河出版社”出版的所有書(shū)籍 # ----連表查詢,使用另一個(gè)表的屬性時(shí)要使用雙下劃線 ret = models.Book.objects.filter(publisher__name='沙河出版社')# 查找每個(gè)出版社出版價(jià)格最高的書(shū)籍價(jià)格 # ----annotate分組聚合,分組后就一定要使用聚合函數(shù),annotate在官方文檔的意思是注釋的意思,給表中每行的數(shù)據(jù)添加注釋 # ----對(duì)annotate前的表進(jìn)行分組,annotate前有values的話,是以values中的值進(jìn)行分組,沒(méi)有values默認(rèn)以annotate前表的id進(jìn)行分組 ret = models.Publisher.objects.annotate(max=Max('book__price')).values('name', 'max', )ret = models.Book.objects.values('publisher__name').annotate(max=Max('price')).values('publisher_id', 'max', 'title') # 查找每個(gè)出版社出版價(jià)格最高的書(shū)籍價(jià)格,這是我之前做的方法,也是正確的可以相較而看# 單表分組,book表以publisher_id分組,統(tǒng)計(jì)每組的最大價(jià)格,注意后面的values()中不要包含book表的字段(如果后面的values中包含了book的字段如'title',那么會(huì)以 'publisher_id'和'title'一起進(jìn)行分組,這樣就亂了)# 這種方法有個(gè)問(wèn)題是不同publisher_id但是同一個(gè)出版社名字的不會(huì)被分到一組ret = models.Book.objects.values('publisher_id').annotate(Max('price')).values('publisher_id','max')# 連表分組,book表和publisher表聯(lián)合,以publisher表的name進(jìn)行分組,統(tǒng)計(jì)每組的最大價(jià)格,正確答案,也符合sql語(yǔ)句的查詢邏輯ret = models.Book.objects.values('publisher__name').annotate(Max('price')).values('publisher_id','max')# 單表分組,連表查詢 ,以publisher表的id進(jìn)行分組,查詢book的最大價(jià)格,同樣也是有不同publisher_id但是同一個(gè)出版社名字的不會(huì)被分到一組的問(wèn)題ret = models.Publisher.objects.annotate(Max('book__price')).values('book__price__max')# 單表分組,連表查詢 ,以publisher表的name進(jìn)行分組,查詢book的最大價(jià)格,不會(huì)有上述問(wèn)題,比較符合人的邏輯ret = models.Publisher.objects.values('name').annotate(Max('book__price')).values('book__price__max')# 查找每個(gè)出版社的名字以及出的書(shū)籍?dāng)?shù)量 # ----這里的Count計(jì)數(shù)的是以publisher分組的book對(duì)象, ret = models.Publisher.objects.annotate(count=Count('book')).values()# 查找書(shū)名是“跟金老板學(xué)開(kāi)車”的書(shū)的出版社出版的其他書(shū)籍的名字和價(jià)格 # ---1,找到出版了“跟金老板學(xué)開(kāi)車”的書(shū)的出版社 models.Publisher.objects.get(book__title='跟金老板學(xué)開(kāi)車') # ---2,篩選出是上述出版社出版的書(shū),使用publisher出版社對(duì)象進(jìn)行篩選 models.Book.objects.filter(publisher=models.Publisher.objects.get(book__title='跟金老板學(xué)開(kāi)車') # ---3.在這些書(shū)里排除 '跟金老板學(xué)開(kāi)車'的書(shū) .exclude(title='跟金老板學(xué)開(kāi)車') ret = models.Book.objects.filter(publisher=models.Publisher.objects.get(book__title='跟金老板學(xué)開(kāi)車')).exclude(title='跟金老板學(xué)開(kāi)車').values('title', 'price')# 法2 # ---1,找到出版了“跟金老板學(xué)開(kāi)車”的書(shū)的出版社 # ---2,通過(guò)外鍵book_set 找到該出版社出版的所有書(shū)籍,此時(shí)的對(duì)象列表已經(jīng)不是出版社,而是書(shū)籍 # ---3,排除 '跟金老板學(xué)開(kāi)車'的書(shū) ret = models.Publisher.objects.get(book__title='跟金老板學(xué)開(kāi)車').book_set.exclude(title='跟金老板學(xué)開(kāi)車').values('title', 'price')# 查找書(shū)名是“跟金老板學(xué)開(kāi)車”的書(shū)的作者們的姓名以及出版的所有書(shū)籍名稱和價(jià)錢# 這樣是有問(wèn)題的,不能這么寫(xiě) ret = models.Author.objects.filter(book__title='跟金老板學(xué)開(kāi)車').values('name', 'book__title', 'book__price').distinct()# 這樣是有問(wèn)題的,不能這么寫(xiě),見(jiàn)下面代碼 ret = models.Book.objects.get(title='跟金老板學(xué)開(kāi)車').author.values('name', 'book__title', 'book__price').distinct()# ---1,找到“跟金老板學(xué)開(kāi)車”的書(shū)籍對(duì)象 # ---2,找到寫(xiě)了'跟金老板學(xué)開(kāi)車'書(shū)籍的所有的作者對(duì)象 # ---3,在所有書(shū)籍中篩選作者在上述作者對(duì)象的書(shū)籍 ret = models.Book.objects.filter(author__in=models.Author.objects.filter(book=models.Book.objects.filter(title='跟金老板學(xué)開(kāi)車'))).values('author__name', 'title', 'price') # 簡(jiǎn)化 ret = models.Book.objects.filter(author__in=models.Author.objects.filter(book__title='跟金老板學(xué)開(kāi)車')).values('author__name', 'title', 'price')

?

# 顯示sql語(yǔ)句的命令,在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',},} } 顯示sql語(yǔ)句的命令,在settings中添加下面代碼

?補(bǔ)充

基于雙下劃線的跨表查詢?

Django 還提供了一種直觀而高效的方式在查詢(lookups)中表示關(guān)聯(lián)關(guān)系,它能自動(dòng)確認(rèn) SQL JOIN 聯(lián)系。要做跨關(guān)系查詢,就使用兩個(gè)下劃線來(lái)鏈接模型(model)間關(guān)聯(lián)字段的名稱,直到最終鏈接到你想要的 model 為止。

關(guān)鍵點(diǎn):正向查詢按字段,反向查詢按表明。

?

# 練習(xí)1: 查詢?nèi)嗣癯霭嫔绯霭孢^(guò)的所有書(shū)籍的名字與價(jià)格(一對(duì)多)

# 正向查詢 按字段:publish

queryResult=Book.objects
            .filter(publish__name="人民出版社")
            .values_list("title","price")

# 反向查詢 按表名:book

queryResult=Publish.objects
              .filter(name="人民出版社")
              .values_list("book__title","book__price")

?

# 練習(xí)2: 查詢egon出過(guò)的所有書(shū)籍的名字(多對(duì)多)

# 正向查詢 按字段:authors:
queryResult=Book.objects
            .filter(authors__name="yuan")
            .values_list("title")

# 反向查詢 按表名:book
queryResult=Author.objects
              .filter(name="yuan")
              .values_list("book__title","book__price")


# 練習(xí)3: 查詢?nèi)嗣癯霭嫔绯霭孢^(guò)的所有書(shū)籍的名字以及作者的姓名


# 正向查詢
queryResult=Book.objects
            .filter(publish__name="人民出版社")
            .values_list("title","authors__name")
# 反向查詢
queryResult=Publish.objects
              .filter(name="人民出版社")
              .values_list("book__title","book__authors__age","book__authors__name")


# 練習(xí)4: 手機(jī)號(hào)以151開(kāi)頭的作者出版過(guò)的所有書(shū)籍名稱以及出版社名稱

queryResult=Book.objects
            .filter(authors__authorDetail__telephone__regex="151")
            .values_list("title","publish__name")

注意:

反向查詢時(shí),如果定義了related_name ,則用related_name替換表名,例如:?publish = ForeignKey(Blog, related_name='bookList'):

# 練習(xí)1:? 查詢?nèi)嗣癯霭嫔绯霭孢^(guò)的所有書(shū)籍的名字與價(jià)格(一對(duì)多)

????# 反向查詢 不再按表名:book,而是related_name:bookList ????queryResult=Publish.objects               .filter(name="人民出版社")               .values_list("bookList__title","bookList__price")

轉(zhuǎn)載于:https://www.cnblogs.com/perfey/p/9648474.html

總結(jié)

以上是生活随笔為你收集整理的ORM操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 天天干天天看 | 手机看片日韩福利 | 一区二区三区在线不卡 | 色人阁视频 | 国产精品污视频 | 国产99在线 | 亚洲 | 国模精品一区二区三区 | 五月激情网站 | 四虎视频国产精品免费 | 欧美中文字幕一区二区 | 69精品无码成人久久久久久 | 欧美一区二区三区免费看 | 夜夜成人 | 深夜福利视频导航 | 欧美三级午夜理伦三级中视频 | 成人精品久久久午夜福利 | 国产情侣在线视频 | 色成人亚洲 | 久久久久九九 | 人妻互换 综合 | 国产精品人人做人人爽 | 欧美亚洲久久 | 波多野结衣中文字幕一区二区 | 久久av一区二区三区漫画 | 小镇姑娘1979版 | 激情综合激情五月 | 一道本久久 | 色丁香综合 | 欧美成人精品一区二区 | 国产a免费视频 | 拔插拔插华人 | 性综合网| 久久精品国产久精国产 | 亚洲一区欧美日韩 | 国产综合视频一区 | 超碰成人在线免费观看 | 亚洲成人自拍偷拍 | 国产男女猛烈无遮挡免费视频 | 99精品在线视频观看 | 欧美高清精品一区二区 | 色老板精品凹凸在线视频观看 | 丁香六月欧美 | 国产欧美精品一区二区三区app | 亚洲国产www| 国产精品3 | 极品美女扒开粉嫩小泬 | a天堂在线观看视频 | 黄色av高清 | 91国偷自产一区二区三区观看 | 日韩欧美高清片 | 黄色录像网址 | 国内精品一区二区三区 | 91精品视频网站 | 欧美一级在线视频 | 国产精品1区2区3区4区 | 北条麻妃一区二区三区在线观看 | 国产视频一区二区三区四区 | 欧美区在线 | 国产aa视频 | 1024手机看片日韩 | 亚洲国产精品视频一区 | 亚洲精品国产精华液 | 中文字幕5566 | 强行无套内谢大学生初次 | 久久国产热 | 亚洲欧美国产日韩精品 | 黄色片一区二区三区 | 天天干,天天爽 | 亚洲av无码国产精品色午夜 | 国产精品高潮呻吟久久久 | 轻点好疼好大好爽视频 | 香蕉毛片| 亚洲国产黄色av | 日本69av | 成年视频在线观看 | 国产精品一区二区免费看 | 久久久久18| 美女诱惑一区 | 182午夜视频 | a级片在线| 日韩一区二区三区在线播放 | 夜夜狠 | 久久亚洲AV无码精品 | 黄色在线观看视频网站 | 人人澡超碰碰97碰碰碰 | 97爱爱爱 | 国产无套免费网站69 | 人人人超碰 | 亚洲精华国产精华精华液网站 | 日韩精品免费一区二区三区 | 另类图片亚洲色图 | 亚洲av成人精品毛片 | 免费看国产片在线观看 | 9l视频自拍九色9l视频 | 中文字幕+乱码+中文字幕一区 | 一本加勒比北条麻妃 | 国产精品伦一区二区三级视频 | 波多野结衣一区二区三区中文字幕 | 亚洲性图一区二区三区 |