Django での集約とグループ化 F クエリ Q クエリのトランザクション Cookie とセッション 066
1 集計とグループ化
集計: 結果を取得するためにいくつかのデータを整理および分析します (mysql の集計関数)
1aggregate(*args,**kwargs) :
QuerySet を計算すると、集計値の辞書が返されます。各パラメータは辞書に含まれる戻り値を指定します。つまり、クエリ セットに対して集計が生成されます
from django.db.models import Avg,Min,Sum,Max #クエリ セット全体から統計を生成します。たとえば、セール中のすべての書籍の平均価格を計算したいとします。Django のクエリ構文は、すべての書籍コレクションを記述する方法を提供します。 Book.objects.all().aggregate(Avg( ' price ' )) # {'print_avg':34.35} #ggregate () 句のパラメータは、計算したい集計値を記述します。これは終端句です。 「たとえば、彼はいくつかのキーと値のペアを含む辞書を返します。キーの名前は、フィールドの名前と集計関数に従って自動的に生成されます。名前を指定したい場合は、次の方法で名前を付けることができます: Book.objects.aggregate(average_price=Avg ( ' price ' )) #複数の値をクエリすることもできます。つまり、すべての本の価格の最大値と最小値を知りたい場合は、 Book.objects を使用することもできます。集計(Avg( '価格' ),Max( '価格' ),Min( '価格' ))
グループ化: annotate(*args, **kwargs)
合計値 (または平均または合計) は、クエリ結果内の各オブジェクトに関連付けられたオブジェクトのコレクションをクエリすることによって取得できます。つまり、クエリ セット内の各項目の集計を生成します。
#ケース1: Lu Junyi が出版した書籍の合計価格をクエリする Boo.objects.filter(author__name= ' Lu Junyi ' ).aggregate(Sum( ' price ' )) #Case 2: それぞれの出版社が出版した書籍の合計価格を確認するauthor これには「グループ化の時間です。条件は authors__name です」 Book.objects.values( ' authors__name ' ).annotate(Sum( ' price ' )) #Case 3: 各出版社の最も安い本の価格をクエリする Book.objects .values( ' Publisher__name ' ).annotate(Min( '価格' ))
FクエリとQクエリ
まず F をインポートする必要があります
django.db.models からインポート F
#最初の使用クエリは、前のフィールドベースまたは順方向および逆方向のクエリと組み合わせて実現できます。 #フィールド値の動的な取得とテーブル内の 2 つの列の値の比較 ret = models.Book.objects .filter(kucun__gt =F( ' sale ' )).values() #このステートメントは、在庫が売上より大きい書籍を取得したいと考えています #2 番目の使用法: データの特定の列を操作します #注文をスワイプして書籍の売上を増やしますが、在庫を変更して特定の列に対してバッチ操作を実行することはありません mods.Book.objects.update(sale=F( ' sale ' ) *2 ) #このステートメントは書籍の売上の列を更新できます #単一の列を更新することもできます obj = models.Book.objects.filter(id=1 ).first() obj.sale = 60 obj.save() update と save() の違い #前者はクエリを制限するリスト列のフィールドを更新・修正するだけで、保存は#すべてのフィールドを更新するので
、後者に比べて効率は若干高くなります
。後者 #つまり、すべての更新を実現するために前に all() を追加します。つまり、 models.Book.objects.all().update(sale=1000 ) #テーブルのすべてのフィールドを更新できます
Qクエリ
まず Q をインポートする必要があります
django.db.models からインポート Q
# django.db.models import Q からQ の検索条件 を構築します# 1 Q オブジェクト (django.db.models.Q) は、複数のクエリをより適切に適用できるようにキーワード パラメーターをカプセル化できます q1 = models.Book.objects.filter(Q( title__startswith= ' P ' )).all() print (q1) # [<Book:Python>,<Book:Perl>] # 2 演算子 & (and)、| (or) は組み合わせて使用できます。演算子が 2 つの Q オブジェクトに使用されると、新しい Q オブジェクトが生成されます Q(title__startswith='P') | Q ( title__startswith = ' J ' ) #P または J で始まるすべてのオブジェクトを取得 # 3 Q オブジェクトを ~ 演算子の前に配置して否定を示すことができ、また、否定と非否定の形式で完全な Qを使用することもできます (title__startswith= ' P ' ) |~Q(pub_date__year=2005 ) P で始まる書籍、または出版日が 2005 年以外の書籍を検索します # 4 説明: #キーワード引数を取る各検索関数 (filter()、 exclude()、get() など) には、1 つ以上の Q オブジェクトを # 位置 (名前のない) 引数として渡すこともできます。複数の Q オブジェクト#引数をルックアップ関数に指定すると、引数は「AND」で#結合されます。例えば: Book.objects.get( Q(title__startswith = ' P ' )、 Q(pub_date =date(2005, 5, 2)) | Q(pub_date=日付(2005, 5, 6 )) ) # sql: # SELECT * 世論調査から 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 # 5Q オブジェクトはキーワード パラメータ クエリで使用できますが、キーワード パラメータ クエリの前に Q オブジェクトを置く必要があります
事務
一連の操作が同時に成功するか、アトミック性がまったく保証されないかのどちらかです
app01インポートモデルから django.dbインポートトランザクションから 試してみてください: transaction.atomic() を使用: models.Publisher.objects.create(name = '新華社通信 1 ' ) int( ' aaa ' ) models.Publisher.objects.create(name = '新華社通信 2 ' ) models.Publisher.objects.create(name = ' Xinhua Press 2 ' ) e: print (e) としての例外を除く #このとき、e に進みます。 #エラー メッセージは、基数 10 の int() のリテラルが無効です: 'aaa'
クッキー
定義: ブラウザーに保存されるキーと値のペアのセットは、サーバーによって送信され、ブラウザーに保存されるキーと値のペアのセットです。ブラウザーは、次回サーバーにアクセスするときにこれらのキーと値のペアを自動的に保持します。ブラウザーサーバーが有用な情報を抽出できるように、これらのキーと値のペアが自動的に伝送されます。
原則: コンテンツはサーバーによって生成され、ブラウザは受信後にローカルに保存します。ブラウザが再度アクセスすると、ブラウザはこれらのキーと値のペアを自動的に取得して、サーバーがそのコンテンツを通じてそれが誰であるかを判断できるようにします。クッキー。
特徴:
1. サーバーはブラウザに Cookie を保存するように要求します。
2. ブラウザには設定しない権利があります
3. 次回の訪問時に応答 Cookie を自動的に保持します
ジャンゴでクッキーを操作する
1 クッキーを取得
request.COOKIES[ 'キー' ] request.get_signed_cookie( ' key ' ,default=RAISE_ERROR,salt= '' ,max_age= None) # get_signed_cookie メソッドのパラメータ: # default: デフォルト値 # Salt: 暗号化ソルト # max_age: バックグラウンド制御の有効期限
クッキー2個セット
reo = HttpResponse(...) rep = render(リクエスト,....) rep.set_cookie(キー,値,...) rep.set_signed_cookie(key,value,salt = '暗号化ソルト' ,...) #パラメータ # key, key # value='', value # max_age=None、タイムアウト時間 # Expires=None、タイムアウト時間 (IE では有効期限が必要なので、まだ期限が切れていない場合は設定します) # path='/' Cookie は取得します効果 path/ はルート パスを示します。特殊: ルート パスの Cookie は任意の URL ページからアクセスできます。 # domain=None、Cookie が有効になるドメイン名 secure= False、https 送信 httponly =False は http プロトコルでのみ送信でき、js では取得できません (絶対的なものではなく、基礎となるパケット キャプチャを取得または上書きできます)
3 Cookieを削除する
デフォルトログアウト(リクエスト): rep = リダイレクト(/ 'ログイン/ ' ) rep.delete_cookie( ' user ' ) #ユーザーのブラウザに以前に設定されたユーザーの Cookie 値を削除しますreturn rep
4 ケース定義 Cookie によるログイン
#ページ訪問前にログイン認証を行い、ログイン成功後に直接ログインするページに入る #最初にログインする処理。ログイン情報と Cookie ステータスをデコレータにカプセル化し、デコレータをページに追加するログイン後にのみインターフェイスにアクセスできます #最初にデコレータを 記述しますdef login_required(func): def inner(request, *args, ** kwargs): #Get cookie is_login = request.COOKIES.get( ' is_login ' ) #暗号化されていないCookie # ログインステータスを取得 is_login = request.get_signed_cookie('is_login',salt='day66',default='xx') #Cookieを暗号化 return_url = request.path_info #リダイレクト先のページのアドレスを取得is_login == ' 1 'の場合: ret = func(request, *args, ** kwargs) else : ret = redirect( ' /login/?return_url={} ' .format(return_url)) #ログイン アドレスにはリダイレクトされるアドレスが含まれます print (ret) print (return_url) return ret インナーを返す #ログイン関数 を定義しますdef login(request): if request.method == ' POST ' : #ユーザー名とパスワード、アクセスするページを取得 user = request.POST.get( ' user ' ) pwd = request.POST.get( ' pwd ' ) print (ユーザー) return_url = request.GET.get( ' return_url ' ) #ここでのパスは上記のデコレータから取得されます print (return_url) if user == ' alex ' and pwd == ' 123 ' : #ジャンプアドレスがある場合アドレスにジャンプします。それ以外の場合は、return_url の場合はインデックス ページにアクセスします。 ret =リダイレクト(return_url) else : ret = リダイレクト( ' /index/ ' ) ret.set_cookie( ' is_login ' , ' 1 ' ) #Cookie タイムアウトを設定max_age=5 path path='/home/' # ret.set_signed_cookie('is_login', '1', 'day66') #暗号化された Cookie を設定return ret return render(リクエスト, ' login.html ' ) #応答ページにデコレーターを追加 @login_required defindex (request): return HttpResponse( ' index ' ) #Cookie の削除def logout(リクエスト): ret = redirect( ' /login/ ' ) #删除cookie ret.delete_cookie( ' is_login ' ) # Set-Cookie: is_login=""; 期限切れ=1970 年 1 月 1 日木曜日 00:00:00 GMT; 最大年齢=0; パス=/ return ret
<!DOCTYPE html> <html lang= " ja " > <頭> <meta charset= " UTF-8 " > <title>タイトル</title> </head> <本文> <フォームアクション= ""メソッド= "ポスト" > <p> ユーザー名: <input type= " text " name= " user " > </p> <p> 秘密コード: <入力タイプ= "パスワード"名前= " pwd " > </p> <button>ログイン</button> </form> </body> </html>
セッション
Cookie により状態を保持する必要性はある程度解決されますが、Cookie 自体は最大 4096 バイトをサポートしており、Cookie 自体はクライアントに保存されるため、傍受されたり盗まれたりする可能性があるため、新たな保存が可能なものが必要です。より多くのバイトをサポートし、サーバーに保存するとセキュリティが高くなります。つまり、セッションです。
Django のセッション関連のメソッド:
#セッションのデータを取得、設定、削除 request.session[ ' k1 ' ] request.session.get( ' k1 ' ,なし) 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セッションキー request.session.session_key #セッションの有効期限が現在の日付より前のデータをすべて 削除request.session.clear_expired() #セッションキーがデータベースに存在するかどうかを確認します request.session.exists( " session_key " ) #現在のセッションのセッションデータをすべて 削除request.session.delete() # 現在のセッション データを削除し、セッション Cookie を削除します。 request.session.flush() これは、ユーザーのブラウザが以前のセッション データに再度アクセスできないようにするために使用されます。 たとえば、これは django.contrib.auth.logout() 関数で呼び出されます。 #セッションとCookieのタイムアウト期間を 設定しますrequest.session.set_expiry(value) * valueが整数の場合、セッションは数秒後に期限切れになります。 *値が datatime または timedelta の場合、セッションはこの時間を過ぎると期限切れになります。 *値が 0 の場合、ユーザーがブラウザ セッションを閉じるとセッションは無効になります。 * 値が None の場合、セッションはグローバル セッション無効化ポリシーに依存します。
Djangoでのセッション設定
1.データベースセッション SESSION_ENGINE = ' django.contrib.sessions.backends.db ' #engine (デフォルト) 2.キャッシュセッション SESSION_ENGINE = ' django.contrib.sessions.backends.cache ' #Engine SESSION_CACHE_ALIAS = ' default ' #使用されるキャッシュ エイリアス (デフォルトのメモリ キャッシュ、または memcache)。エイリアスはキャッシュ設定によって異なります。 3.ファイルセッション SESSION_ENGINE = ' django.contrib.sessions.backends.file ' #Engine SESSION_FILE_PATH = なし #キャッシュファイル パス、なしの場合は、tempfile モジュールを使用して一時アドレスを取得します tempfile.gettempdir( ) 4. キャッシュ +データベース SESSION_ENGINE = ' django.contrib.sessions.backends.cached_db ' #引擎 5.暗号化された Cookie セッション SESSION_ENGINE = ' django.contrib.sessions.backends.signed_cookies ' #引擎 その他の一般的な設定項目: SESSION_COOKIE_NAME = " sessionid " #セッション Cookie がブラウザに保存されるときのキー。つまり、 sessionid = ランダムな文字列 (デフォルト) SESSION_COOKIE_PATH = " / " #セッション Cookie が保存されるパス (デフォルト) SESSION_COOKIE_DOMAIN = None #セッション Cookie保存されたドメイン名 (デフォルト) SESSION_COOKIE_SECURE = False #HTTPSが Cookie を送信するかどうか (デフォルト) SESSION_COOKIE_HTTPONLY = True #セッション Cookie が http 送信のみをサポートするかどうか (デフォルト) SESSION_COOKIE_AGE = 1209600 #セッション Cookie の有効期限 (2 週間) (デフォルト) SESSION_EXPIRE_AT_BROWSER_CLOSE = False #セッションを期限切れにするためにブラウザを閉じるかどうか (デフォルト) SESSION_SAVE_EVERY_REQUEST = False #リクエストごとにセッションを保存するかどうか、デフォルトの変更後に保存するかどうか (デフォルト) Django のセッション関連の設定
セッションログインの場合
django.shortcutsからimport render、redirect、HttpResponse django.confからimport global_settings、 django.contrib.sessions.backendsからの設定import db def login_required(func): def inner(request, *args, ** kwargs): # print(request.session.session_key) # セッションの session_key を表示します # print(request.session.exists('r0f6ys1wj4du94w0fzr5lapyoxxzqr93')) #データが存在するかどうかを判定 is_login = request.session.get( ' is_login ' ) #セッションを取得 return_url = request.path_info if is_login == ' 1 ' : ret = func(request, *args, ** kwargs) else : ret = redirect( ' /login/?return_url={} ' .format(return_url)) return ret return inner defログイン(リクエスト): request.method == ' POST 'の場合: ユーザー= request.POST.get( 'ユーザー' ) pwd = request.POST.get( ' pwd ' ) print (ユーザー) return_url = request.GET.get( ' return_url ' ) if user == ' alex ' およびpwd == ' 123 ' : if return_url: ret =リダイレクト(return_url) else : ret = リダイレクト( ' /index/ ' ) request.session[ ' is_login ' ] = ' 1 ' return ret return render(request, ' login.html ' ) @ログインが必要です def home(request): # is_login = request.COOKIES.get('is_login') # if is_login != '1': # return redirect('/login/') return HttpResponse( ' home ' ) @ログインが必要です defインデックス(リクエスト): return HttpResponse( 'インデックス' ) def logout(request): # request.session.delete() # Cookie を削除せずにサーバーのセッション データを削除します request.session.flush() #セッションと Cookie を削除します ret = redirect( ' /login/ ' ) # ret. delete_cookie ('is_login') # Set-Cookie: is_login=""; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Path=/ return ret
この場合、データは mysql データベースに保存されており、データベース内のサンプル データがそれぞれセッション キーとデータであることがわかります。