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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Web框架之Django_06 模型层了解(F查询、Q查询、事务、update和save、only和defer、choice属性、bulk_create)

發布時間:2024/9/30 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Web框架之Django_06 模型层了解(F查询、Q查询、事务、update和save、only和defer、choice属性、bulk_create) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

閱讀目錄

  • 一、F查詢

  • 二、 Q查詢

  • 三、事務

  • 四、補充的一些常用的操作

摘要:

  • F查詢
  • Q查詢
  • 事務

一、F查詢

  • 在上面所有的例子中,我們構造的過濾器都只是將字段值與某個我們自己設定的常量做比較。如果我們要對兩個字段的值做比較,那該怎么做呢?
    Django 提供 F() 來做這樣的比較。F() 的實例可以在查詢中引用字段,來比較同一個 model 實例中兩個不同字段的值。 示例:
    建表:
-------------------------------------------------------------------- 注:如果你對python感興趣,我這有個學習Python基地,里面有很多學習資料,感興趣的+Q群:895817687 --------------------------------------------------------------------from django.db import modelsclass Goods(models.Model):name = models.CharField(max_length=32)price = models.DecimalField(max_digits=8, decimal_places=2)remain = models.BigIntegerField()sold_out = models.BigIntegerField()

插入模塊

from django.db.models import F,Q

例子:查詢賣出數量大于庫存數的商品名稱

res = models.Goods.objects.filter(sold_out__gt=F('remain')).values_list('name', 'sold_out', 'remain') print(res) # <QuerySet [('襪子', 600, 100), ('夾克', 20, 10)]>

F可以幫我們取到表中某個字段對應的值來當作我的篩選條件,而不是我認為自定義常量的條件了,實現了動態比較的效果

Django 支持 F() 對象之間以及 F() 對象和常數之間的加減乘除和取模的操作。基于此可以對表中的數值類型進行數學運算
例子:將每個商品的價格提高50塊

res1 = models.Goods.objects.update(price=F('price')+100)

引申:如何修改char字段,比如將上面的表中商品名稱全部尾部加上‘清倉’兩個字,如何操作?
這里需要使用2個模塊:Concat 和 Value

from django.db.models.functions import Concat from django.db.models import Valueres = models.Goods.objects.update(name=Concat(F('name'), Value('清倉')))

Concat表示進行字符串的拼接操作,參數位置決定了拼接是在頭部拼接還是尾部拼接,Value里面是要新增的拼接值

二、 Q查詢

  • filter()方法匯總的逗號get的條件是與的關系,如果要執行更復雜的查詢,比如or的語句,就會用到Q對象 例子:
    查詢賣出數量大于100或者價格小于300的商品名
from django.db.models import F,Qres = models.Goods.objects.filter(Q(sold_out__gt=100)|Q(price__lt=300)).values_list('name', 'sold_out', 'price') print(res)<QuerySet [('襪子清倉', 600, Decimal('129.90')), ('寸衫清倉', 10, Decimal('229.90'))]>

對條件包裹一層Q時候,filter即可支持交叉并的比較符

# 查詢庫存數是小于等于20,且賣出數不是10的產品 res = models.Goods.objects.filter(Q(remain__lte=20)&~Q(sold_out=12)).values_list('name')

我們可以組合& 和| 操作符以及使用括號進行分組來編寫任意復雜的Q 對象。

同時,Q 對象可以使用~ 操作符取反,這允許組合正常的查詢和取反(NOT) 查詢。

# 查詢產品名包含新款或者爆款,且庫存大于60的產品res = models.Goods.objects.filter(Q(name__contains='新款')|Q(name__contains='爆款'), remain__gt=60).values_list('name')

查詢函數可以混合使用Q 對象和關鍵字參數。所有提供給查詢函數的參數(關鍵字參數或Q 對象)都將"AND”在一起。但是,如果出現Q 對象,它必須位于所有關鍵字參數的前面

  • 重點使用方法補充:
實例化Q對象:q = Q() q.connector = 'or' # 默認q之間的條件都是與關系,這里改成or關系 q.children.append(('name','sgt')) # 插入第一個條件,注意這里傳的是一個元祖 q.children.append(('password','123')) # 可以繼續插入條件 # q對象支持直接放入filter括號內,它們之間默認是and關系,可以通過上面的q.connect = 'or'來修改成或關系 models.User.objects.filter(q) # 這里面就是查詢的條件們,它們之間默認是與關系,可以修改成or關系

三、事務

  • 定義:將多個sql語句操作變成原子性操作,要么同時成功,有一個失敗在里面就回滾到原來的狀態,保證數據的完整性和一致性(NoSQL數據庫對事務則是部分支持)
# 事務 # 購買商品 # 產品表中修改數據:賣出數+1,庫存-1 from django.db.models import F from django.db import transaction try :with transaction.atomic():models.Goods.objects.filter(id=1).update(remain=F('remain')-1, sold_out=F('sold_out')+1) except Exception as e:print(e)

四、補充的一些常用的操作

  • update()與save()的區別

兩者都是對數據的修改保存操作,但是save()函數是將數據列的全部數據項全部重新寫一遍,而update()則是針對修改的項進行針對的更新效率高耗時少

所以以后對數據的修改保存用update()

  • 讓我們通過orm對數據庫操作時候,讓終端顯示內部查詢操作sql語句:
    在Django項目的settings.py文件中,在最后復制粘貼如下代碼:
LOGGING = {'version': 1,'disable_existing_loggers': False,'handlers': {'console':{'level':'DEBUG','class':'logging.StreamHandler',},},'loggers': {'django.db.backends': {'handlers': ['console'],'propagate': True,'level':'DEBUG',},} }

配置好之后,再執行任何對數據庫進行操作的語句時,會自動將Django執行的sql語句打印到pycharm終端上
補充:
除了配置外,還可以通過一點query即可查看查詢語句,具體操作如下:

  • only 與 defer 拿到的是一個對象 兩者是相反的
    (前提設置:設置每次操作數據庫時候都會有sql語句現實在pycharm終端,上面已說明步驟) 先看看only:

    看看defer
    choice屬性
    choice這個屬性,用來限制用戶做出選擇的范圍。比如說性別的選擇(男或女)
class MyUser(models.Model):name = models.CharField(max_length=32)password = models.CharField(max_length=32)choices = ((1, '男'), (2, '女'), (3, '其它'))gender = models.CharField(choices=choices, default=1, max_length=5)

choice接收一個元組(保證值不可變),同理每一個選項也是由一個元組(value,display_name)構成。顯而易見,display_name就是要在頁面中展示的。

如何取到value和displayname?

比如說實例一個User對象user_obj,
user_obj.gender = value (通過屬性取value)
user_obj.get_gender_display() = display_name (通過 get_屬性_display()方法取display_name)
在模板中可以通過模板語言{{ user_obj.gender }}很簡單地顯示value,但不能直接調用get屬性_display方法(模板畢竟是模板語言),要解決這個問題,可以用自定義過濾器來搞定:
來回顧一下如何自定義過濾器:
1,在應用名下新建一個名為templatetags文件夾
2,在該文件夾內新建一個py文件,名字隨意
3,在該py文件內添加固定代碼和自定義過濾器代碼

from django import templateregister = template.Library()@register.filter(name='displayName') def displayName(obj):res = obj.get_gender_displayreturn res()# 視圖層: from django.shortcuts import render, HttpResponse,reverse # Create your views here. from app01 import models def index(request):obj = models.MyUser.objects.filter(pk=1).first()return render(request, 'index.html', locals())# 前端(html頁面): {% load my_file %} {{ obj|displayName}}

bulk_create批量插入數據
當我們使用orm來一次性新增很多表記錄的時候,等待結果的時間會非常的慢,如果一次性需要批量插入很多數據的時候就需要使用bulk_create來批量插入數據

import randomuser_list = ['用戶[{}]'.format(i) for i in range(100)] data = [] for j in user_list:data.append(models.MyUser(name=j, password='123', gender=str(random.choice([1, 2, 3])))) models.MyUser.objects.bulk_create(data)
  • select_related和prefetch_related
def select_related(self, *fields)性能相關:表之間進行join連表操作,一次性獲取關聯的數據。總結:1. select_related主要針一對一和多對一關系進行優化。2. select_related使用SQL的JOIN語句進行優化,通過減少SQL查詢的次數來進行優化、提高性能。def prefetch_related(self, *lookups)性能相關:多表連表操作時速度會慢,使用其執行多次SQL查詢在Python代碼中實現連表操作。總結:1. 對于多對多字段(ManyToManyField)和一對多字段,可以使用prefetch_related()來進行優化。2. prefetch_related()的優化方式是分別查詢每個表,然后用Python處理他們之間的關系。

總結

以上是生活随笔為你收集整理的Web框架之Django_06 模型层了解(F查询、Q查询、事务、update和save、only和defer、choice属性、bulk_create)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。