Django -聚合分組,FQ操作, cookie, session
一. 聚合查詢和分組
1. 聚合 aggregate(*args, **kwargs)
對一組資料進行統計分析, 通過對QuerySet進行計算, 返回一個聚合值得字典. arrgregate()中每一個引數都指定一個包含在字典中的返回值. 既在查詢集上生成聚合.
from django.db.models import Avg,Min,Sum,Max Book.objects.all().aggregate(Avg('price') #{'price__avg': 34.35} #aggregate()字句的引數描述了我們想要計算的聚合值, 在這個例子中, 是Book模型中price欄位的平均值#aggregate()是QuerySet的一個終止字句, 意思是說, 他返回一個包含一些鍵值對的字典, 鍵的名稱是聚合值的識別符號, 值是計算出來的聚合值, 鍵的名稱是按照欄位和聚合函式的名稱自動生成出來的, 如果你想要為聚合值指定一個名稱, 可以向聚合字句提供它: Book.objects.aggregate(average_price=Avg('price')) {'average_price': 34.35} #如果你也想知道所有圖書的最大值和最小值, 可以這樣查詢: Book.objects.aggregate(Avg('price'), Max('price'), Min('price') # {'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}
2. 分組 annotate(*args, **kwargs)
把查詢物件的某個欄位進行分組, 按照分組的欄位屬性進行查詢
# 查詢我吃西紅柿出的書的總價格
Book.objects.filter(authors__name='alex').aggregate(Sum('price')) #{'price__sum': Decimal('140.00')}
# 查詢各個作者出的書的總價格,這裡就涉及到分組, 分組條件authors__name
Book.object.values("authors__name").annotate(Sum('price')) #[{},{},{},{}]
# 查詢各個出版社最便宜的書價是多少
Book.objects.values("publisher__name").annotate(Min('price')) [{},{},{},{},{}]
二. F查詢和Q查詢
方便用來多個欄位要求的查詢
#F 使用查詢條件的值,專門取物件中某列值的操作
# F使用查詢條件的值, 專門取物件中某列值得操作 from django.db.models import F #動態的獲取欄位的值 ret= models.Book.objects.filter(kucun__gt=F('sale')).values() # update更新指定欄位 models.Book.objects.all().update(sale=F('sale')*2)
#Q 構建搜尋條件
from django.db.models import Q ret = models.Book.object.filter(Q(~Q(id__lt=3)) | Q(id__gt=5))&Q(id__lt=4)) ~取反 |或 &與AND
三. 事務
一系列操作要同時成功執行,或都不執行, 保證原子性操作
from app01 import models from dango.db import transaction try: with transacyion.atomic(): models.Publisher.objects.create(name='新華出版社1') models.Publisher.objects.create(name='新華出版社1') models.Publisher.objects.create(name='新華出版社1') except Exception as e: print(e) #同時成功才能執行, 有一個失敗,就失敗
五. Cookie
1.什麼是Cookie?
Cookie指的是一端小資訊, 他是伺服器傳送出來儲存在瀏覽器上的一組組鍵值對, 下次訪問伺服器時瀏覽器會自動攜帶這些鍵值對, 以便伺服器提取有用資訊.
Cookie的原理 >>
Coolie的工作原理是: 由伺服器產生內容, 瀏覽器收到請求後儲存在本地; 當瀏覽器再次訪問時,瀏覽器會帶上Coolie, 這樣伺服器就能通過Cookie的內容來判斷這個是'誰'了.
檢視Cookie
2. Django中操作Cookie
a. 設定Cookie
引數:
key: 鍵
value='': 值
max_age=None: 超出時間
expires=None: 超時時間(IE requires expires, so set it if hasn't been already.)
path='/': Cookie生效的路徑,/表示根路徑, 特殊的: 根路徑的cookie可以被任何url的頁面訪問
domain=None: Cookie生效的域名
semain=False: https傳輸
httponly=False: 只能http協議傳輸, 無法被javaScript獲取(不是絕對, 底層抓包可以獲取到也可以被覆蓋)
rep = HttpResponse(...) rep = render(request, ...) rep.set_cookie(key,value,...) rep.set_signed_cookie(key, value, salt='加密鹽',...)
b. 獲取
default: 預設值
salt: 加密鹽
max_age: 後臺控制過期時間
request.COOKIKES['key'] request.get_signed_cookie('key', default=RAISE_ERROR, salt='',max_age=None)
c.刪除
def logout(request): rep = redirect("/login/") rep.delete_cookie("user") #刪除使用者瀏覽器上之前設定的user的cookie return rep
Cookie版登入校驗
def check_login(func): @wraps(func) def inner(request, *args, **kwargs): next_url = request.get_full_path() if request.get_signed_cookie("login", salt="SSS", default=None) == "yes": # 已經登入的使用者... return func(request, *args, **kwargs) else: # 沒有登入的使用者,跳轉剛到登入頁面 return redirect("/login/?next={}".format(next_url)) return inner def login(request): if request.method == "POST": username = request.POST.get("username") passwd = request.POST.get("password") if username == "xxx" and passwd == "dashabi": next_url = request.GET.get("next") if next_url and next_url != "/logout/": response = redirect(next_url) else: response = redirect("/class_list/") response.set_signed_cookie("login", "yes", salt="SSS") return response return render(request, "login.html")View Code
六. session
定義: 儲存在伺服器端的一組組鍵值對
原因: 1. cookie的長度和個數收到限制
2. cookie儲存在瀏覽器本地不安全
a, 設定
request.session['is_login'] = '1' #設定session資料 request.session.set_expiry(5) #設定超時時間
b, 獲取
request.session.get('is_login') # 獲取session
c, 刪除
request.session.delete() #刪除伺服器的sess資料, 不刪除cookie request.session.flush() #刪除session和cookie
配置資訊
from django.conf import global_settings,settings # 全域性的配置和區域性的配置 from django.contrib.sessions.backends import db
# 獲取、設定、刪除Session中資料 request.session['k1'] request.session.get('k1',None) request.session['k1'] = 123 request.session.setdefault('k1',123) # 存在則不設定 del request.session['k1'] # 所有 鍵、值、鍵值對 request.session.keys() request.session.values() request.session.items() request.session.iterkeys() request.session.itervalues() request.session.iteritems() # 會話session的key request.session.session_key # 將所有Session失效日期小於當前日期的資料刪除 request.session.clear_expired() # 檢查會話session的key在資料庫中是否存在 request.session.exists("session_key") # 刪除當前會話的所有Session資料 request.session.delete() # 刪除當前的會話資料並刪除會話的Cookie。 request.session.flush() 這用於確保前面的會話資料不可以再次被使用者的瀏覽器訪問 例如,django.contrib.auth.logout() 函式中就會呼叫它。 # 設定會話Session和Cookie的超時時間 request.session.set_expiry(value) * 如果value是個整數,session會在些秒數後失效。 * 如果value是個datatime或timedelta,session就會在這個時間後失效。 * 如果value是0,使用者關閉瀏覽器session就會失效。 * 如果value是None,session會依賴全域性session失效策略。Session相關方法
from functools import wraps def check_login(func): @wraps(func) def inner(request, *args, **kwargs): next_url = request.get_full_path() if request.session.get("user"): return func(request, *args, **kwargs) else: return redirect("/login/?next={}".format(next_url)) return inner def login(request): if request.method == "POST": user = request.POST.get("user") pwd = request.POST.get("pwd") if user == "alex" and pwd == "alex1234": # 設定session request.session["user"] = user # 獲取跳到登陸頁面之前的URL next_url = request.GET.get("next") # 如果有,就跳轉回登陸之前的URL if next_url: return redirect(next_url) # 否則預設跳轉到index頁面 else: return redirect("/index/") return render(request, "login.html") @check_login def logout(request): # 刪除所有當前請求相關的session request.session.delete() return redirect("/login/") @check_login def index(request): current_user = request.session.get("user", None) return render(request, "index.html", {"user": current_user})Session版登入驗證
1. 資料庫Session SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(預設) 2. 快取Session SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 SESSION_CACHE_ALIAS = 'default' # 使用的快取別名(預設記憶體快取,也可以是memcache),此處別名依賴快取的設定 3. 檔案Session SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 SESSION_FILE_PATH = None # 快取檔案路徑,如果為None,則使用tempfile模組獲取一個臨時地址tempfile.gettempdir() 4. 快取+資料庫 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 5. 加密Cookie Session SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎 其他公用設定項: SESSION_COOKIE_NAME = "sessionid" # Session的cookie儲存在瀏覽器上時的key,即:sessionid=隨機字串(預設) SESSION_COOKIE_PATH = "/" # Session的cookie儲存的路徑(預設) SESSION_COOKIE_DOMAIN = None # Session的cookie儲存的域名(預設) SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie(預設) SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支援http傳輸(預設) SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(預設) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過期(預設) SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都儲存Session,預設修改之後才儲存(預設)