ジャンゴのご紹介
使用フィニッシャー
ページングは、データベースのデータの過剰な数が、ページワンタイム表示を良く見ていない、我々はポケットベルを使用することができ、データが複数回表示さページ上で非常に一般的です。
データベース1.1内に大量のデータを挿入します
Booklist=[]
for i in range(100):
Booklist.append(Book(title="book"+str(i),price=30+i*i))
Book.objects.bulk_create(Booklist)
次のオブジェクトを使用するとbulk_create()
、バッチで挿入することができます
1.2インポートモジュール
django.core.paginatorインポートページネータから
ページャ1.3の例
ページネータ=ページネータ(book_list、8)データの最初のリストは、各ページのために第二のデータ
方法に関する1.4ページャオブジェクト
方法 作用
paginator.count() 数据总数
paginator.num_pages() 总页数
paginator.page_range() 页码的迭代器
Nはデータページを取得する
current_page = paginator.page(1)
最初のページのリストを取得します
方法 作用
current_page.object_list 获取第n页对象列表
current_page.has_next() 是否有下一页
current_page.next_page_number() 下一页的页码
current_page.has_previous() 是否有上一页
current_page.previous_page_number() 上一页的页码
注:入力paginator.page(1)内のページ数、ページの最大数未満1以上である場合、エラーがEmptyPageが報告されます。
キャプチャEmptyPage間違った方法
django.core.paginator輸入EmptyPageから
エラーを導入、使用トライキャッチエラー
try:
内容
except EmptyPage as e:
current_page=paginator.page(1)
ページング1.5の簡単な例
views.py中
def books(request):
book_list = Book.objects.all()
from django.core.paginator import Paginator,EmptyPage
paginator = Paginator(book_list,3)
num_pages = paginator.num_pages
current_page_num = int(request.GET.get("page",1))
if num_pages > 11:
if current_page_num < 5:
page_range = range(1,11)
elif current_page_num+5 > num_pages:
page_range = range(num_pages-10,num_pages+1)
else:
page_range = range(current_page_num-5,current_page_num+5)
else:
page_range = paginator.page_range
try:
current_page = paginator.page(current_page_num)
except EmptyPage as e:
current_page = paginator.page(1)
return render(request,"book.html",locals())
でbook.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>分页练习</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script
src="https://code.jquery.com/jquery-3.3.1.js"
integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
crossorigin="anonymous"></script>
</head>
<body>
<p>OK</p>
<table class="table table-striped">
<tbody>
{#显示当前页面#}
{% for book in current_page %}
<tr>
<td>{{ book.nid }}</td>
<td>{{ book.title }}</td>
<td>{{ book.price}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{#显示页码#}
<ul class="pagination">
{% if current_page.has_previous %}
<li>
<a href="?page={{ current_page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% endif %}
{% for item in page_range %}
{% if item == current_page_num %}
<li class="active"><a href="?page={{ item }}">{{ item }}</a></li>
{% else %}
<li><a href="?page={{ item }}">{{ item }}</a></li>
{% endif %}
{% endfor %}
{% if current_page.has_next %}
<li>
<a href="?page={{ current_page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% endif %}
</ul>
</body>
{#<script>#}
{# $(".pagination li a").click(function () {#}
{# $(this).parent().addClass("active").siblings("li").removeClass("active")#}
{# })#}
{#</script>#}
</html>
フォームコンポーネント
成分形式主な機能は、フィールドテストの関数である、ファンクションキーの形式をチェック
2.1検査フィールド機能
2.11インポートフォームアセンブリ
ジャンゴインポートフォームから
2.12コンポーネントクラスを作成するフォームを使用
class UserForm(forms.Form):
name = forms.CharField(min_length=4)
email=forms.EmailField()
名前フィールドではない以下の4バイト、電子メールフィールドの必須メール形式よりも、最小
注:このクラスはforms.Formを継承しなければならない
だけで、他のフィールドに渡された、フィールドでユーザーフォームをチェックは無視され、チェックされません。チェック欄が空白にすることはできませんとき、フィールドの形式は、存在します
いくつかの一般的に使用される関数とそのパラメータのチェック
チェック機能
文字列をチェックするCharFieldです、あなたは最小の長さまたは最大長MAX_LENGTHのMIN_LENGTHを提供することができます
DecimalFieldはデジタル認証確認は、末尾のスペースは無視され、そしてMAX_VALUEは、全体の長さを制御MIN_VALUE、及びdecimal.Decimal値として与えられるべきです。+ max_digitsは、ビットの総数整数小数を可能にします。
小数点以下の最大許容数をDecimal_places。
EmailFieldは、有効な電子メールアドレスである、およびオプションのパラメータMAX_LENGTH MIN_LENGTH
FileFieldに非空のファイルデータはMAX_LENGTHの最大ファイルサイズとファイルが空allow_empty_fileことができるかどうか、フォームにバインドされています
所定値フロート、MAX_VALUE及び任意MIN_VALUEかどうかを確認しFloatField
与えられた値が整数であるかどうかを確認IntegerFieldと。またMAX_VALUEおよびMIN_VALUE
2.13インスタンス化オブジェクトのフォームA将需要验证的表单值传入,检验是否合法 form=UserForm({"name":"yuan","email":"123"}) 也可以直接传入POST字典(但是前段键值必须与form一一对应) form = UserForm(request.POST)
2.14表示チェックフィールドの結果
関連API
- そうでなければFalse、すべての戻り真をチェックして()form.is_valid
- 辞書にform.cleaned_data復帰、あなたは成功したフィールドを見て確認することができます(キーが配置されています)
- form.errorsは(エラーキーのキーをチェックし、エラーメッセージリストの値)検証エラーのフィールドを見ることができ
2.15レンダリングタギング
フォームコンポーネントも自動的にフォームの形で私たちのためにフォームチェックフィールドをレンダリングすることができます
次のように具体的な方法があります
2.16フォームインスタンス化するファーストクラス
値を渡さない)(=ユーザーフォーム形成
テンプレートでの2.17の使用形態
方法1:{{フォームフィールド}}使用ラベルが対応する入力タグをレンダリングすることができる
HTMLに
<form action="" method="post">
{% csrf_token %}
<p>用户名:{{ form.name }}</p>
<p>密码:{{ form.pwd }}</p>
<p>再次确认密码:{{ form.re_pwd }}</p>
<p>邮箱:{{ form.email }}</p>
<p>电话:{{ form.tel }}</p>
<input type="submit" value="注册">
</form>
ビュー関数で
フォームユーザーフォーム=()は、
コンポーネントが自動的にタグのname属性は、対応するフィールドの名前となり生成するフォーム
例えば
ユーザ名:{{}} form.name
等価に
ユーザー名:
第二の方法:ループのラベルに使用して
<form action="" method="post">
{% csrf_token %}
{% for field in form %}
<p>
<label>{{ field.label }}</label>
{{ field }} <span>{{ field.errors.0 }}</span>
</p>
{% endfor %}
<input type="submit" value="注册">
</form>
使用すると、{{フォームフィールド.LABEL}}がなければならない対応するラベルをレンダリングすることができます
注意:ラベル、タグのフィールド名は、デフォルトで表示されますが、フォームクラスを作成する際に指定する必要がありますラベルの内容を表示する場合
class UserForm(forms.Form):
name = forms.CharField(min_length=4,label="用户名")
email=forms.EmailField(label="邮箱")
ラベル指定されたパラメータを使用して、効果をレンダリングすると、このユーザーフォームを使用するのと同じです
<p>用户名:{{ form.name }}</p>
<p>邮箱:{{ form.email }}</p>
<p>方式三</p>
<form action="" method="post">
{% csrf_token %}
{{ form.as_ul }}
<input type="submit" value="注册">
</form>
使用して{{form.as_ul}}自動的にすべてのフィールドをレンダリングし、各フィールドの入力ラベルレンダリングULおよびラップで処理を用いて
、それぞれPで)as_p()、as_table(によって選択することができる、テーブルパッケージラベル
2.2ディスプレイインターフェイスフォームをリセット
ユーザーフォーム入力エラーが、我々は独自のパラメータを渡すことができる場合、各入力の値の値は、迅速にリセットインターフェースをレンダリングすることができるフォームコンポーネントを使用して、ページをレンダリングするためにリセットし
、単にいくつかの手順を設定することによって
def register(request):
if request.method =="POST":
form = UserForm(request.POST)
if form.is_valid():
return HttpResponse("ok")
else:
return render(request,"register.html",locals())
else:
form = UserForm()
return render(request,"register.html",locals())
ユーザーがブラウザのページを使用してアクセスした場合簡単に言えば、GETリクエストを送信、我々は、ブラウザが自動的に各フィールドの空白ラベルをパラメータなしで渡したオブジェクトをレンダリングしますフォームフォーム=ユーザーフォームを()を使用する
ユーザーがいる場合フォームが送信されたとき、我々は=ユーザーフォーム(request.POST)は同じ、パラメータを持つオブジェクトを形成して、フォームをインスタンス化し、ブラウザがフォームを送信するために渡されたパラメータの内容をレンダリングします。
入力エラー、ユーザの入力によって返されたフォームの内容が空でないとき、つまり、ユーザが間違ったコンテンツを最後に入力した時間があります
2.3エラーメッセージを表示する方法
私たちは、HTMLページに入力されたエラー情報の後にデータを確認したい場合は、我々はこれを行うことができます
HTMLフォームで渡されたオブジェクトの2.31まずインスタンス
form = UserForm()
return render(request,"register.html",locals())
したがって、すべてのローカル変数に直接(フォームを含む)HTMLテンプレートにマッピングされた場合
2.32のコールHTMLテンプレートで対応するオブジェクト
<form action="" method="post">
{% csrf_token %}
<p>用户名:{{ form.name }}<span>{{ form.name.errors.0 }}</span></p>
<p>密码:{{ form.pwd }}<span>{{ form.pwd.errors.0 }}</span></p>
<p>再次确认密码:{{ form.re_pwd }}<span>{{ form.re_pwd.errors.0 }}</span></p>
<p>邮箱:{{ form.email }}<span>{{ form.email.errors.0 }}</span></p>
<p>电话:{{ form.tel }}<span>{{ form.tel.errors.0 }}</span></p>
<input type="submit" value="注册">
</form>
対応するフィールドエラー場合{{形。タグフィールド.errors.0を}}を使用して、適切なエラーメッセージ({{形。.Errors}}フィールドは、エラーのリストでレンダリングすることができ、我々は、{{形。フィールド.errorsを使用します。 0}}のみ)最初のエラーメッセージを取ります
設定パラメータの2.4形式
使用ウィジェットモジュールは、私たちはクラスの対応する形式にパラメータフィールドを設定することができます
2.41インポートモジュール
フォームdjango.formsは、ウィジェットをインポート
要素タイプが生成されたテンプレートに設けられ2.42アセンブリ形
我々はCharFieldですの種類を確認するためにフィールドを設定すると、あるHTMLテンプレートのタグを生成します入力し
、我々はどのように行う、ラベル生成の種類を変更したい場合は?
例:
pwd =forms.CharField(min_length=4,widget=widgets.PasswordInput())
使用widget参数可以设置标签类型,PasswordInput()代表将自动生成```类型标签
テンプレートの属性設定要素を生成2.43組立フォーム
我々はいくつかのデフォルトの属性を追加生成の各要素にしたい場合は、我々は、関数のパラメータ要素タイプのattrsにを使用することができます
例:名前= forms.CharField(MIN_LENGTH = 4 、ウィジェット= widgets.TextInput(attrsに= {「クラス」 「フォームコントロールは」}) )
生成されたデフォルトクラス属性の各要素に追加され、フォームコントロールで
の必要に格納されたキーを設定することによりATTRS
2.5チェックローカルフック
上記の条件のチェックサムフィールドが小さすぎると、私たちのニーズを満たすことができない、私たちは、チェックの内容をカスタマイズすることができ、それがローカルフック使用して、各フィールドに必要な
使用を
2.51原理
私たちは、フォームオブジェクト()関数の下でs_valid呼び出すと、フィールドの検証を行います。チェックに成功置かclean_data辞書、チェックが例外をスロー失敗し、例外ハンドラは、失敗したフィールドとエラーメッセージストアをチェックしますエラー辞書。そして、検証は故意にユーザー定義関数のために、フックを残して成功ジャンゴ、ときに
コードの一部ジャンゴ:
if hasattr(self, 'clean_%s' % name):
value = getattr(self, 'clean_%s' % name)()
self.cleaned_data[name] = value
2.52最初のエラーのタイプをインポート
from django.core.exceptions import ValidationError
ValidationError是用来抛出异常时的错误类型
2.53その後、クラスの形で機能clean_フィールドを作成
デフclean_name(自己):
2.54 cleaned_dataが正常の値を使用して検証取得しました
ヴァル= self.cleaned_data.get(「名前」)
検証成功辞書を得ることができますcleaned_dataを使用して
例2.55
電話番号フィールドが11であることを確認します
def clean_tel(self):
val = self.cleaned_data.get("tel")
if len(val)==11:
return val
else:
raise ValidationError("手机号位数错误")
条件が満たされた場合、それが返されるように、それらを検証し、成功電話番号のフォームからフィールドの元のうちにチェックを外し、そうでない場合は例外がスローされます
2.6グローバルフック
我々はパスワードなどの確認のための複数のフィールド間の関係を、欲しいとパスワードを確認した場合と同じが必要ですが、検証のための単一のフィールドの値の一部のみのフック付き。これは、我々はグローバルフック必要があるということな気候である
最初のステップ、ValidationErrorをに導入されたエラーの同じタイプを
2.61原理
ジャンゴまた、彼らは、関数にチェックしたいコンテンツの書き込み、この関数を上書き指示し、ユーザーは検証のために複数のフィールドとの関係を望んでいるとき、きれいな機能を残し
たコードの一部にdjangoの
きれいなコードを
def clean(self):
"""
Hook for doing any extra form-wide cleaning after Field.clean() has been
called on every field. Any ValidationError raised by this method will
not be associated with a particular field; it will have a special-case
association with the field named '__all__'.
"""
return self.cleaned_data
クラスできれいなフォーム機能の作成2.62
デフクリーン(自己):
2.63例
チェックサム確認パスワードとパスワードが同じです
def clean(self):
pwd = self.cleaned_data.get("pwd")
re_pwd = self.cleaned_data.get("re_pwd")
if pwd and re_pwd:
if pwd == re_pwd:
return self.cleaned_data
else:
raise ValidationError("两次密码不一致")
return self.cleaned_data
チェックが成功した場合は、元clean_dataフィールドの検証への復帰は、ValidationErrorを投げ失敗します
注:{。} {フォームフィールド.errors}テンプレートは、エラーメッセージ単一のフィールドの検証が失敗し、我々が使用できる
グローバルフックスローされた例外がグローバル誤差に格納されます、我々は、Pythonでclean_errors =フォームを使用する必要があります。 errors.get(「すべての」)、エラーメッセージを取得するためにテンプレート{{clean_errors.0を}}を使用してグローバルエラーメッセージを取得し
、検証が失敗した場合、単一のフィールドの代表者:我々はPWDとre_pwd場合も判断チェックするときグローバルフックを実行することではありません。パスワードやパスワードが間違っフォーマット、パスワードを確認し、確認が同じでないのであれば、パスワードのみを報告したり、パスワードの確認が正しくフォーマットされています。
ミドルウェア
#####ミドルウェアは3.1とは何ですか?
そしてrespone間の要求ハンドラは
settings.pyミドルウェアは、配列に格納されたミドルウェアであります
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'app01.my_middlewares.AuthMiddleware',
'app01.my_middlewares.IpLimitMiddleware',
]
ミドルウェア・プロセスの
クライアント- 「モジュールwsgiref - 」ミドルウェア- 「のURLルーティング制御- 」データベースモデル、HTMLテンプレート
3.2カスタムミドルウェア
3.21 my_middlewares.pyような、中間格納するフォルダを作成
3.22インポート対応するクラス
from django.utils.deprecation import MiddlewareMixin
適切なクラスを作成する3.23(MiddlewareMixinを継承しなければなりません)
class CustomerMiddleware(MiddlewareMixin)
def process_request(self,request):
print("Customer")
パラメータが要求しなければなりません。値を返しません、それはデフォルトのnoneに戻ろう
ミドルウェアミドルウェアアレイに登録3.24
MIDDLEWARE = [
...
...
...
"app01.my_middlewares.CustomerMiddleware",
]
3.25ミドルウェアの役割は何ですか?
只要浏览器访问服务器,就会访问中间件
作用:大部分视图函数要使用的代码就可以放到中间件中
比如,将登陆函数放到中间件中,访问服务器就会调用中间件,验证是否登录
使用中间件限制用户访问的频率
3.26 mainメソッド
このクラスでは、あなたはどのようないくつかの主要なメソッドを定義することができます
メソッドの定義
- process一デフprocess一(自己、リクエスト):
- process_response(自己、リクエスト、レスポンス)デフprocess_response:
- process_view process_view(自己、リクエスト、コールバック、callback_args、callback_kwargs)|
- process_exception(自己、リクエスト、例外)デフにprocess_exception:
注意:
リクエストパラメータ渡す必要があり、各クラス
process_responseは(本体渡さresponeパラメータ応答関数戻りビュー)ボディタイプに応じて、返さなければならない
process一中間リターン直接HttpRespone、バックミドルウェアを行わない場合これは、ミドルウェアに直接ジャンプします1
process_responeの
ビュー機能を与えられたときにprocess_exceptionが正常に行わ、実行されない;効果:黄色所定のインターフェイスの経験代替応答例外が関数処理、捕捉例外に対応するエラーの本来の機能に戻ったときに
実行順序を
、通常下:
process_request- "URLコントローラ- " process_view- "ビュー機能- " process_responseの
ビュー時に誤差関数
process_request- "URLコントローラ- " process_view- "ビュー機能・エラー- " process_exception-「process_response
ミドルウェアにおけるsetting.py実行順序リスト
中間体が複数存在する、サーバ関数は上から下へ順次実行を介してデータを送信し、ビューを順次アップ底から行われる機能が戻る
要求process一を順次各クライアント上を通過します次process一に渡さ
process_responseを渡す順次に応答して本体上を通過する各process_response
例えば:
process_request1-》process_request2-》url控制器-》process_view1-》》process_view2-》视图函数出错-》process_exception2-》process_exception1-》process_response2-》process_response1
例3.3
3.31プラスユーザ認証サーバのページ
我々はいくつかのページをしたい場合は、ユーザログが、我々は、ユーザ認証デコレータデコレータの外に加えて使用することができることを示した後にのみ、あなたはまた、ミドルウェアを使用することができます
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect
from authDemo import settings
class AuthMiddleware(MiddlewareMixin):
def process_request(self,request):
if request.path in settings.WHITE_LIST:
return None
# 用户登录验证
if not request.user.is_authenticated:
return redirect("/login/")
URLを格納するために使用WHITE_LISTリストを作成settings.pyは、そのようなログイン、登録、解除URLなどの追加のユーザ認証を必要としない
ユーザーがログインしていない場合、我々はページ/ログインにリダイレクトされます/
3.32 IPアクセス制限査定率
私たちはクライアントIPの周波数へのアクセスを制限したい場合は、我々はミドルウェアを使用することができます
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect,HttpResponse
from authDemo import settings
import datetime
class IpLimitMiddleware(MiddlewareMixin):
def process_request(self,request):
if request.META.get("HTTP_X_FORWARDED_FOR"):
ip = request.META["HTTP_X_FORWARDED_FOR"]
else:
ip = request.META["REMOTE_ADDR"]
now_min = datetime.datetime.now().minute
if ip in settings.BLACK_LIST: #查询ip是否在黑名单内
return HttpResponse("你已经被加入黑名单")
elif ip in settings.IP_LIST:
if settings.IP_LIST[ip]["min"] == now_min:
settings.IP_LIST[ip]["times"] += 1
if settings.IP_LIST[ip]["times"] >= settings.LIMIT_VISIT_TIMES: #判断用户访问次数是否太快,返回提醒用户
if settings.IP_LIST[ip]["times"] >= settings.MAX_VISIT_TIMES: #如果用户访问次数非常多,加入黑名单
settings.BLACK_LIST.append(ip)
return HttpResponse("访问频率过快")
else:
settings.IP_LIST[ip]["times"] = 0
settings.IP_LIST[ip]["min"] = now_min
else:
settings.IP_LIST[ip] = {"times":1,"min":now_min}
settings.py里创建一个IP_LIST字典,用来存储客户端ip和其他信息(其实可以单独放入数据库一个表中,不过从数据库中读取没有内存中读取快,访问速度会受到影响)
如果用户使用代理request.META["REMOTE_ADDR"]抓不到真实地址,所以我们首先使用request.META["HTTP_X_FORWARDED_FOR"]来获取用户真实地址
我们将其用户ip和访问次数储存,在settings.py中设置一个常量LIMIT_VISIT_TIMES,超过这个次数不让用户访问网页;MAX_VISIT_TIMES超过这个次数,将这个ip加入黑名单
オリジナルリンク:https://blog.csdn.net/xgy123xx/article/details/82722185