多对多三种创建方式
forms校验性组件
django settings源码
昨日のコンテンツ
ajax结合sweetalert
自己写一个删除按钮的确认框
去github上下载sweetalert源码 你只需要使用里面dist文件夹
gitlab
公司自己搭建
码云
参考示例书写即可
二次开发能力
基于人家已经写好的功能修改
1.先看别人的配置参数
2.前期就是猜
3.整体修改
linux
redis
mongodb
github
git
批量处理
bulk_create()
当你要批量操作数据库的时候 一定要减少走数据库的频率
数据的分页展示
django其实有内置的分页模块
但是该模块不好用,书写麻烦,功能不健全
自定义分页
1.queryset支持切片操作
2.研究当前页 每页展示多少条数据 起始位置 终止位置
3.前端代码不一定非要在前端书写 后端也可以
把自定义的代码拷贝到本地
基本使用
将代码放入到一个py文件中
导入该文件中的类
1.生成该类的对象
展示数据的总条数
用户想访问的页码
默认参数每页展示几条数据
分页页码的个数 奇数位
2.前端使用
qeuryset部分
|safe
多くの-な方法を作成するには、3つの方法
悪化し、カプセル化の度合いが高いスケーラビリティ
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の動作方法
- 追加
削除が
設定
明確な
- 追加
短所
- 第三に、テーブルが自動的に作成され、スケーラビリティがフィールドを変更、テーブル貧しい拡張することができません
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)
ベネフィット
- 第三に、テーブル名とフィールド名のすべてのフィールドの数は、独自に定義することができます
短所
- ORMクロステーブルのクエリは、もはや正と負の概念がない、サポートされていません
- この方法は、フィールドを変更するために使用することはできません
- 追加
削除が
設定
明確な
- 追加
3半自動through='',through_fields=(外键字段)
推奨
# 半自动
class Book(models.Model):
title = models.CharField(max_length=32)
# 多对多关系字段
authors = models.ManyToManyField(to='Authors',through='Book2Authors',through_fields=('authors','book'))
class Authors(models.Model):
name = models.CharField(max_length=32)
# 自建第三张表
class Book2Authors(models.Model):
book = models.ForeignKey(to='Book')
author = models.ForeignKey(to='Authors')
# 该表中有任意多的外键字段
through='第三张表名'
自動的に作成し、手動で第三のテーブル名を作成しない指定、および関連しますthrough_fields=('','')
2つのフィールドのテーブルとの間の多くの関係、外部キーを保持している最後に第3のテーブルを指定し、フィールドの前に
当你的ManyToMany只有一个参数to的情况下orm会自动帮你创建第三张表
如果你加了throug和through_fields那么orm就不会自动帮你创建第三张表,但是他会在内部帮你维护关系,让你能够继续使用orm的跨表查询
through 自己制定第三张表关系
through_fields 自己制定第三张表中到底哪两个字段维护这表与表之间的多对多关系,外键在哪个表中,参数放在前面
ベネフィット
- あなたは、テーブル内の任意の3番目のフィールドを追加し、変更することができます
- サポートORMクロステーブルのクエリ
短所
- テーブルのフィールドの変更方法をサポートしていません。
- 追加
削除
明確な
セット
フォームコンポーネント
1.簡単な紹介
需求:
注册页面,获取用户输入的用户名和密码
提交到后端之后,后端需要对用户名和密码进行校验
用户名中不能含有'金 瓶 梅'
密码不能少于三位
如果不符合,展示响应的错误信息
景色
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
def register(request):
# get请求来的时候直接走的是空值字典
errors = {'username':'','password':''}
# 当请求方式是post时给字典赋值
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if 'jinpingmei' in username:
errors['username'] = '不符合社会主义核心价值观'
if len(password) < 4:
errors['password'] = '注意注意太少了'
return render(request,'register.html',locals())
register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>简易校验用户的输入功能</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
<form action="" method="post">
<p>username
<input type="text" name="username">
<span style="color: red">{{ errors.username }}</span>
</p>
<p>password
<input type="text" name="password">
<span style="color: red">{{ errors.password }}</span>
</p>
<input type="submit">
</form>
</body>
</html>
行うには上記のコードの簡単な事
- レンダリングタグ - 手動で書かれたHTMLコードは、ユーザー入力を取得します
- パリティデータ - データのバックエンドをチェックするためにデータを渡します
- 情報を表示 - データエラーがある場合は、エラーメッセージを表示する必要があります
コンポーネント役割を2.forms
行うことができ、上記の3つのステップであります
- タグをレンダリング
- データをチェック
- 情報を表示
フォームコンポーネントを使用しての最初のステップは、あなたがクラスを記述する必要があります
from django import forms
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()
テストpycharm
右下角 python console
自动创建测试环境
2.1検査データ
辞書に渡して、作成されたクラスのインスタンスを作成し、辞書には、データ検証の必要性、オブジェクトを取得していますform_obj
form_obj = views.MyForm({'username':'jason','password':'12','email':'123'})
1. is_vaild
合法性を確認します
form_obj.is_valid()
False # 只有当你的数据全部符合校验规则的情况下 结果才是True 否则都为False
2. .errors
フィールドと非準拠の理由を参照してください
form_obj.errors
{
'password': ['Ensure this value has at least 3 characters (it has 2).'],
'email': ['Enter a valid email address.']
}
3. cleaned_data
に沿ってデータを表示
form_obj.cleaned_data
{'username': 'jason'}
シーケンス(値によって渡され、複数の値と数)の4伝統的な価値観
合格しなければならない以下のフィールドは、デフォルト値で定義されていないコンポーネントのフォームを渡します
少传了字段会报错
form_obj = views.MyForm({'username':'jason','password':'12345'})
form_obj.is_valid()
False
form_obj.errors
{'email': ['This field is required.']}
あなたは合格した場合のコンポーネントが複数のフィールドのクラスに定義されたフォームをチェックしますフォームは影響はありません
多设置字段并不会影响
form_obj = views.MyForm({'username':'jason','password':'12345','email':'[email protected]','xxx':'嘿嘿嘿'})
form_obj.is_valid()
True
2.2レンダリングラベル
空のオブジェクトクラスフォームを生成する第1のステップ伴い
class MyForm(forms.Form):
pass
def index(request):
第一步需要生成一个空的forms类的对象
form_obj = MyForm()
直接将生成的对象传递给前端页面
return render(request,'index.html',locals())
- fromsコンポーネントを使用すると、ユーザーの入力をレンダリングするラベルは、あなた自身の手を追加するために、送信ボタンをレンダリングする助けにはなりません得るのを助けます
最初のas_p as_ul as_table
互いに直接すべての情報をレンダリング
reg.html
Copy<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<title>Title</title>
</head>
<body>
<div class="container">
<div class="row">
{#第一种渲染方式#}
<div class="col-md-offset-2 col-md-8">
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<hr>
{{ form.as_table }}
<hr>
{{ form.as_ul }}
<hr>
<input type="submit" value="提交" class="btn btn-success">
</form>
</div>
</div>
</div>
</body>
</html>
このように、Djangoのパッケージの度合いが高すぎる、我々はそれが唯一の早期迅速ビルドページに使用することができますので、完全にカスタムスタイルも、そして使用するためのテストを行うことができないです。最終的なレンダリング結果の巨大な醜い...非常に基本的な実際的な考慮はしないでくださいそれは。
第2
個々のラベルをレンダリング
<p>forms组件渲染标签方式2(不推荐使用,写起来太多)</p>
{#input框的提示信息 获取input框#}
{{ form_obj.username.label }}{{ form_obj.username }}
私たちは、フォームオブジェクトを使用する場合。フィールド名は、単一の入力ボックスをレンダリングするようにすることを見つけることができます。コンポーネントのレンダリングを確認し、いくつかの法律が完了した後にフォームを見つけることができます。
第三の
上記のように、このアプローチはまた、ある悪い所を有する場合、フィールドより同様のスタイル、より多くのトラブルを追加するために、各1つの必要性、あなたは三番目の方法を使用する必要があり、この時間が経過した後
トラバーサルフォームオブジェクトは、唯一のフォームオブジェクトに小さな変更を加える必要があります。ラベルをレンダリングするために、あなたは同じ効果を得ることができます
{% for form in form_obj %}
<p>{{ form.label }}{{ form }}</p>
{% endfor %}
あなたは、タグページをレンダリングするクラスラベルのデフォルト設定を定義することができます
class RegForm(forms.Form):
# 接下来的定义需要与模型表的字段类型一一对应
username = forms.CharField(
max_length=15, # 用户名最大长度为15
min_length=3, # 用户名的最小长度为3
label='用户名', # 渲染出在页面上的标签的名字
)
password = forms.CharField(
max_length=15, # 密码最大长度为15
min_length=3, # 密码的最小长度为3
label='密码', # 渲染出在页面上的标签的名字
)
2.3情報表示
ブラウザのフロントエンドの検証フォームが設定フォームではありません指示しますnovalidate
パラメータが可能
<form action="" method="post" novalidate>
着信データをチェックする方法フロントエンドユーザー
エラーメッセージを表示
views
def index(request):
# 获得空的forms类对象
form_obj = MyForm()
# 校验前端用户传入的数据
if request.method == 'POST':
# 获取用户的数据,在request.POST中,forms组件校验数据
form_obj = MyForm(request.POST) # 该变量名一定要与上面的变量名一致
if form_obj.is_valid():
print(form_obj.cleaned_data)
return HttpResponse('数据全部')
else:
print(form_obj.errors)
return render(request,'index.html',locals())
-------------------------------------------------------
index.html
<form action="" method="post" novalidate>
{% for form in form_obj %}
<p>
{{ form.label }}{{ form }}
{# form 等价于方式2中的对象点字段名(使用.0获取列表中的信心)#}
<span>{{ form.errors.0 }}</span>
</p>
{% endfor %}
<input type="submit">
</form>
パラメータ設定
class MyForm(forms.Form):
# username字段 最少三位,最多八位
username = forms.CharField(max_length=8,min_length=3,label='用户名',
error_messages={
'max_length':'用户名最长8位',
'min_length':'用户名最短3位',
'required':'用户名不能为空'
})
# email字段 必须是邮箱格式
email = forms.EmailField(label='邮箱',
error_messages={
'required':'邮箱不能为空',
'invalid':'邮箱格式错误'
})
label=
設定メッセージerror_messages={}
設定エラーメッセージ- 必要なことは空にすることはできません
- セットメールボックス形式無効
- 内蔵チェッカー検証
RegexValidator定期点検
2.4検査データを追加します
内蔵チェッカー
内置的校验器
from django.core.validators import RegexValidator
validators=[
RegexValidator(r'^[0-9]+$', '请输入数字'),
RegexValidator(r'^159[0-9]+$', '数字必须以159开头'),
]
HOOKフック関数
それは後にチェックし、一般的に完全に準拠を確認するために開始されます
明らかに一人でチェックする上記のタイプは、より複雑な検証のいくつかを満たしていない、たとえば、ユーザ名が敏感な単語を含めることはできません、二度パスワードは、それを検証する必要があり、一貫している必要があります。
内部クラスのメソッドは、関数である、あなたは、in vivo検証で任意の関数を書くことができます
ローカルフック clean_字段值
チェックの単一のフィールド
.add_error
エラーメッセージは、フィールドに提示しました
フィールドデータに戻りますreturn username
类中定义函数:
# 校验用户名中不能含有666
def clean_username(self):
# 校验通过的数据在 cleaned_data
username = self.cleaned_data.get('username')
# 第二层的判断
if '666' in username:
# 给username字段对应的框显示错误信息
self.add_error('username','后面的是报错')
# 将username数据返回
return username
グローバルフック clean
複数のフィールド間の関係を確認してください
グローバルデータを返しますreturn self.cleaned_data
类中
# 校验两次密码是否一致
def clean(self):
password = self.cleaned_data.get('password')
re_password = self.cleaned_data.get('re_password')
if not password == re_password:
self.add_error('re_password','两次密码不一致')
# 将全局的数据返回
return self.cleaned_data
補足知識
小猿取经博客园密码
xiaoyuanqujing@666
他のフィールドとパラメータ
セット入力に対応Lableメッセージ
デフォルト値を設定するための初期入力ブロック
必要なデフォルトはTrue、制御フィールドは空です
パスワードのテキストが表示される設定ウィジェット
widget=forms.widgets.PasswordInput()
from django.forms import widgets widget=forms.widgets.PasswordInput()
widget=forms.widgets.TextInput()
括号内可以设置类内的属性 填写字典{},添加多个参数空格连接 widget=forms.widgets.TextInput({'class':'form-control c1 c2','username':'jack'})
初期
初期値、初期値入力ボックスの内側。
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="密码")
パスワード
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()
)
選択フィールドの考慮事項
selectタグを使用するときは、データベースから取得することが可能な構成オプションの選択に注意を払うする必要がありますが、それはない、すぐに更新取らstaticフィールドの値であるため、我々はリアルタイムの更新を達成するために、コンストラクタの選択を無効にする必要があります。
一つの方法:
from django.forms import Form
from django.forms import widgets
from django.forms import fields
class MyForm(Form):
user = fields.ChoiceField(
# choices=((1, '上海'), (2, '北京'),),
initial=2,
widget=widgets.Select
)
def __init__(self, *args, **kwargs):
super(MyForm,self).__init__(*args, **kwargs)
# self.fields['user'].choices = ((1, '上海'), (2, '北京'),)
# 或
self.fields['user'].choices = models.Classes.objects.all().values_list('id','caption')
第二の方法:
from django import forms
from django.forms import fields
from django.forms import models as form_model
class FInfo(forms.Form):
authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all()) # 多选
# authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all()) # 单选