ディレクトリ
ジャンゴ対多の関係
完全自動モードを作成します。1.
class Book(models.Model):
title = models.CharField(max_length=32)
# 多对多关系字段
authors = models.ManyToManyField(to='Authors')
class Authors(models.Model):
name = models.CharField(max_length=32)
利点:すべて自動的にORMの作成を支援しているあなたは、3番目のテーブルを完了するために運転開始を持っていません
4つの電界を動作させる方法は、第3のテーブルを構築し
add
remove
set
clear
不十分:自動的に作成された3番目の表は、拡張スケーラビリティが悪いのテーブル内のフィールドを変更することはできません
2本の純粋なウェイラインと手を作成します。2.
class Book(models.Model):
title = models.CharField(max_length=32)
class Authors(models.Model):
name = models.CharField(max_length=32)
class Book2Authors(models.Model):
book = models.ForeignKey(to="Book")
author = models.ForeignKey(to="Authors")
create_time = models.DateField(auto_now_add = True)
利点:表の3番目のフィールドの数とフィールド名のすべてが独自に定義することができます
不十分:ORMクロステーブルのクエリは、もはや、もはや正と負のコンセプトによってサポートされていません
add
remove
set
clear
3.半自動(推奨)
class Book(models.Model):
title = models.CharField(max_length=32)
# 多对多关系字段
authors = models.ManyToManyField(to='Authors',through='Book2Author',through_fields=("book","authors"))
# 不通过orm创建,而是通过第三张表中->through='Book2Author'的through_fields=("authors","book"),authors和book字段
# through_fields=("authors","book")中的"authors"字段,可以这样记:在哪张表里面该字段就放在最前面
"""
当你的ManyToManyField只有一个参数to的情况下 orm会自动帮你创建第三张表
如果你加了through和through_fields那么orm就不会自动帮你创建第三张表 但是它会在内部帮你维护关系 让你能够继续使用orm的跨表查询
through 自己指定第三张关系表
through_fields 自己指定第三张关系表中 到底哪两个字段维护者表与表之间的多对多关系
"""
class Authors(models.Model):
name = models.CharField(max_length=32)
# 多对多关系字段 等价
books = models.ManyToManyField(to='Book', through='Book2Author', through_fields=("authors","book"))
class Book2Author(models.Model):
book = models.ForeignKey(to='Book')
authors = models.ForeignKey(to='Authors')
- ORMはによって作成されますが、第三のテーブルによってされていません - > through_fields =(「著者」、「本」)、作家や本のフィールドの=「Book2Author」を介して
- 「著者」フィールドにthrough_fields =(「著者」、「本」)は、それが参照することができます。フィールドの内側に前面にどのテーブルに
- テーブルには、できるだけ多くの外部キーフィールドを有することができます
- これは、任意のフィールドに拡張することができます
利点:あなたは、テーブル内の任意の3番目のフィールドを追加し、変更することができ
、サポートORMのクロステーブル・クエリの
欠点:サポートされていません
add
remove
set
clear
組立チェックフォーム
forms组件
前戏
需求:
1.写一个注册页面 获取用户输入的用户名和密码
提交到后端之后 后端需要对用户名和密码做校验
用户名里面不能含有葫芦娃
密码不能少于三位
如果不符合 展示对应的错误信息
forms组件 能够做的事情
1.手动书写html代码获取用户输入 >> >> >> 渲染标签
2.将数据转递给后端做数据校验 >> >> >> 校验数据
3.如果数据有错误 你还展示了错误信息 >> >> >> 展示信息
事前にクラスを記述する必要があることコンポーネントのフォームを使用しての前提
from django import forms
class MyForm(forms.Form):
# username字段 最少三位 最多八位
username = forms.CharField(max_length=8,min_length=3)
# password字段 最少三位 最多八位
password = forms.CharField(max_length=8,min_length=3)
# email字段 必须是邮箱格式
email = forms.EmailField()
校验数据
# 1.给写好的类 传字典数据(待校验的数据)
form_obj = views.MyForm({'username':'jason','password':'12','email':'123'})
# 2.如何查看校验的数据是否合法
form_obj.is_valid()
False # 只有当你的数据全部符合校验规则的情况下 结果才是True 否则都为False
# 3.如何查看不符合规则的字段及错误的理由
form_obj.errors
{
'password': ['Ensure this value has at least 3 characters (it has 2).'],
'email': ['Enter a valid email address.']
}
# 4.如何查看符合校验规则的数据
form_obj.cleaned_data
{'username': 'jason'}
# 5.forms组件中 定义的字段默认都是必须传值的 不能少传
form_obj = views.MyForm({'username':'jason','password':'12345'})
form_obj.is_valid()
False
form_obj.errors
{'email': ['This field is required.']}
# 6.forms组件只会校验forms类中定义的字段 如果你多传了 不会有任何影响
form_obj = views.MyForm({'username':'jason','password':'12345','email':'[email protected]','xxx':'嘿嘿嘿'})
form_obj.is_valid()
True
渲染标签
forms组件只会帮你渲染获取用户输入的标签 不会帮你渲染提交按钮 需要你自己手动添加
<p>forms组件渲染标签方式1:封装程度态高 不推荐使用 但是可以用在本地测试</p>
{{ form_obj.as_p }} <!--自动渲染所有input框 -->
{{ form_obj.as_ul }}
{{ form_obj.as_table }}
<p>forms组件渲染标签方式2:不推荐使用 写起来太烦了</p>
{{ form_obj.username.label }}{{ form_obj.username }}
{{ form_obj.username.label }}{{ form_obj.password }}
{{ form_obj.username.label }}{{ form_obj.email }}
<p>forms组件渲染标签方式3:推荐使用 </p>
{% for form in form_obj %}
<p>{{ form.label }}{{ form }}</p> <!--form 等价于你方式2中的对象点字段名-->
{% endfor %}
展示信息
<p>forms组件渲染标签方式3:推荐使用 </p>
<form action="" method="post" novalidate>
{% for forms in form_obj %}
<p>
{{ forms.label }}{{ forms }}
<span>{{ forms.errors.0 }}</span>
</p> <!--form 等价于你方式2中的对象点字段名-->
{% endfor %}
<input type="submit">
</form>
登録機能を実現するためのフォームコンポーネントを使用します
良いReGFormカテゴリを定義します。
from django import forms
# 按照Django form组件的要求自己写一个类
class RegForm(forms.Form):
name = forms.CharField(label="用户名")
pwd = forms.CharField(label="密码")
ビュー機能を書きます
# 使用form组件实现注册方式
def register2(request):
form_obj = RegForm()
if request.method == "POST":
# 实例化form对象的时候,把post提交过来的数据直接传进去
form_obj = RegForm(request.POST)
# 调用form_obj校验数据的方法
if form_obj.is_valid():
return HttpResponse("注册成功")
return render(request, "register2.html", {"form_obj": form_obj})
login.htmll
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册2</title>
</head>
<body>
<form action="/reg2/" method="post" novalidate autocomplete="off">
{% csrf_token %}
<div>
<label for="{{ form_obj.name.id_for_label }}">{{ form_obj.name.label }}</label>
{{ form_obj.name }} {{ form_obj.name.errors.0 }}
</div>
<div>
<label for="{{ form_obj.pwd.id_for_label }}">{{ form_obj.pwd.label }}</label>
{{ form_obj.pwd }} {{ form_obj.pwd.errors.0 }}
</div>
<div>
<input type="submit" class="btn btn-success" value="注册">
</div>
</form>
</body>
</html>
ページの効果の調査結果は、関数の形を検証参照してください。
フロントページオブジェクトクラス生成されたフォーム - >関数発生HTMLタグ
ページのユーザー名とパスワードが空または間違った後にプロンプトが表示されます場合は - >ユーザーが機能をチェックし提出しました
ユーザーが再び間違って入力すると、入力ボックス内の最後のコンテンツの遺跡は、 - >最後に入力された内容にしてください
共通のフォームフィールドとプラグイン
初期
初期値は、その初期値の入力ブロック
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名",
initial="张三" # 设置默认值
)
pwd = forms.CharField(min_length=6, label="密码")
error_messages
書き換えエラーメッセージ
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名",
initial="张三",
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短8位"
}
)
pwd = forms.CharField(min_length=6, label="密码")
password
class LoginForm(forms.Form):
...
pwd = forms.CharField(
min_length=6,
label="密码",
widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
)
radioSelect
値は、単一の無線の文字列です。
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名",
initial="张三",
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短8位"
}
)
pwd = forms.CharField(min_length=6, label="密码")
gender = forms.fields.ChoiceField(
choices=((1, "男"), (2, "女"), (3, "保密")),
label="性别",
initial=3,
widget=forms.widgets.RadioSelect()
)
ラジオを選択
class LoginForm(forms.Form):
...
hobby = forms.ChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
label="爱好",
initial=3,
widget=forms.widgets.Select()
)
複数の選択肢を選択
class LoginForm(forms.Form):
...
hobby = forms.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
label="爱好",
initial=[1, 3],
widget=forms.widgets.SelectMultiple()
)
ラジオのチェックボックス
class LoginForm(forms.Form):
...
keep = forms.ChoiceField(
label="是否记住密码",
initial="checked",
widget=forms.widgets.CheckboxInput()
)
複数選択チェックボックス
class LoginForm(forms.Form):
...
hobby = forms.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=[1, 3],
widget=forms.widgets.CheckboxSelectMultiple()
)
データ検証
通常、フロントおよびデータの後端をチェックしている必要があります
不可欠なフロントエンドの検証と壊れやすいではなく、
バックエンドの検証がなければならず、非常に包括的でなければならない
フォームチェックフォームを追加していないブラウザを伝えるためにどのようnovalidate
なパラメータが可能に
<form action="" method="post" novalidate>
内蔵チェッカー
from django.core.validators import RegexValidator
validators=[
RegexValidator(r'^[0-9]+$', '请输入数字'),
RegexValidator(r'^159[0-9]+$', '数字必须以159开头'),
]
HOOKフック関数
あなたは上記のチェックのすべてを考えるとき、あなたがフック関数を使用することを検討することができ、あなたのニーズを満たしていない
生体機能における機能であるあなたは、任意のチェックコードを書くことができます
ローカルフック
あなたは、単一のフィールドを確認したいです
グローバルフック
あなたは、複数のフィールドを確認したいです