慕课网-Django入门到进阶-更适合Python小白的系统课程-第5章Django中的Form表单的使用-5-3模型表单
第5章 Django 中的 Form 表单的使用
5-3 模型表单
概念介绍
1.模型表单是 model 层的模型与 form 表单结合起来,通过表单层作为中介,渲染出前端表单,并通过表单直接读写数据库
2.模型表单基础模块继承于:forms.ModelForm
from django.forms import ModelForm
from myapp.models import Article
# Create the form class
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['pub_date', 'headline', 'content', 'reporter']
# Creating a form to add an article.
form = ArticleForm()
# Creating a form to change an existing article
article = Article.objects.get(pk=1)
form = ArticleForm(instance=article)
Model 字段类型与 form 字段类型
| 模型字段 | 表单字段 |
| AutoField | 不呈现在表单中 |
| BigAutoField | 不呈现在表单中 |
| BigIntegerField | IntegerField 将 min_value 设置为 -9223372036854775808,将 max_value 设置为 9223372036854775807 |
| BooleanField | BooleanField |
| CharField | CharField 将 max_length 设置为模型字段的 max_length,如果模型中设置了 null=True,会将 empty_value 设置为 None。 |
| DateField | DateField |
| DateTimeField | DateTimeField |
| DecimalField | DecimalField |
| EmailField | EmailField |
| FileField | FileField |
| FilePathField | FilePathField |
| FloatField | FloatField |
| ForeignKey | ModelChoiceField |
| ImageField | ImageField |
| IntegerField | IntegerField |
| IPAddressField | IPAddressField |
| GenericIPAddresField | GenericIPAddresField |
| ManyToManyField | ModelMultipleChoiceField |
| NullBooleanField | NullBooleanField |
| SmallIntegerField | IntegerField |
| TextField | CharfField 设置中 widget=forms.Textarea |
| TimeField | TimeField |
| URLField | URLField |
特殊说明
1.当 model 字段设置了blank=True,表单 required=False
2.表单 label 会设置 model 字段的 verbose_name
3.ForeignKey 由 django.forms.ModelChoiceField 表示,它是一个 ChoiceField,其选项是一个模型的 QuerySet
4.ManyToManyField 由 django.forms.ModelMultipleChoiceField 表示,它是一个 MultpleChoiceField,其选项为一个模型 QuerySet
实例
1.在命令行窗口进入 MySQL 界面,创建数据库 forms
create database forms default charset=utf8;
2.在项目 form 下目录 form,修改文件 settings.py,修改数据库配置
# 数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'forms',
'USER':'root',
'PASSWORD':'123456',
'HOST':'127.0.0.1',
'PORT':'3306',
'OPTIONS':{
"init_command":"SET sql_mode='STRICT_TRANS_TABLES'"
},
}
}
3.在项目 form 下目录 app,修改文件 models.py
from django.db import models
class Auth(models.Model):
username = models.CharField(max_length=18)
password = models.CharField(max_length=18)
def __str__(self):
return 'username:{}'.format(self.username)
4.在项目 form 下,命令行窗口创建数据库表 app_auth
python manage.py makemigrations python manage.py migrate

5.在命令行窗口进入 MySQL 界面,查看数据表是否生成成功
use fomrs; show tables; show create table app_auth;

6.在项目 form 下目录 app,修改文件 forms.py,添加类 AuthModelForm
from django import forms
from django.forms import fields
from .models import Auth as AuthModel
class AuthModelForm(forms.ModelForm):
class Meta:
model = AuthModel
fields = ['username', 'password']
exclude = [] # 输入不转成表单字段的 model 字段
field_classes = { # 定义字段的类型,一般会按照 model 的类型自动转换
'username': forms.CharField,
'password': forms.CharField,
}
labels = {
'username': '用户名',
'password': '密码',
}
widgets = {
'username': forms.TextInput(
attrs={'placeholder':'请输入用户名'}
),
'password': forms.PasswordInput(
attrs={'placeholder':'请输入密码'}
),
}
error_messages = {
'username': {'required': '用户名不可以为空'},
'password': {'min_length': '最少不能低于10个字符'},
}
def clean_username(self):
username = self.cleaned_data.get('username')
if len(username) > 10:
raise forms.ValidationError('用户名最大不能超过10')
return username
class Auth(forms.Form):
username = fields.CharField(
max_length=18,
min_length=3,
required=True,
label="用户名",
widget=forms.TextInput(attrs={'placeholder':'最大不能超过18字符'}),
error_messages={'max_length':'最大不能超过18字符!'}
)
password = fields.CharField(
widget=forms.PasswordInput(attrs={'placeholder':'请输入密码'}),
label="密码",
required=True,
min_length=10,
error_messages={'min_length':'最小不能低于10个字符'}
)
def clean(self):
password = self.cleaned_data.get('password', '')
if not password:
raise forms.ValidationError('密码不可以为空!')
def clean_username(self):
username = self.cleaned_data.get('username', '')
if len(username) > 18:
raise forms.ValidationError('用户名最大不能超过18')
return username
7.在项目 form 下目录 app,修改文件 views.py,引用 AuthModelForm,把 Auth 改成 AuthModelForm
from django.shortcuts import render, redirect, reverse
from django.views.generic import View
from .forms import Auth, AuthModelForm
class Regist(View):
TEMPLATE = 'regist.html'
def get(self, request):
form = AuthModelForm()
return render(request, self.TEMPLATE, {'form': form})
def post(self, request):
# username = request.POST.get('username')
# password = request.POST.get('password')
form = AuthModelForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
print('username:', username)
print('password', password)
else:
return render(request, self.TEMPLATE, {'form':form})
return redirect(reverse('regist'))
8.在项目 form 下命令行窗口进入服务
python manage.py runserver 127.0.0.1:8000
9.测试


10.在项目 form 下目录 app,修改文件 views.py,保存数据,添加代码 form.save()
from django.shortcuts import render, redirect, reverse
from django.views.generic import View
from .forms import Auth, AuthModelForm
class Regist(View):
TEMPLATE = 'regist.html'
def get(self, request):
form = AuthModelForm()
return render(request, self.TEMPLATE, {'form': form})
def post(self, request):
# username = request.POST.get('username')
# password = request.POST.get('password')
form = AuthModelForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
form.save()
else:
return render(request, self.TEMPLATE, {'form':form})
return redirect(reverse('regist'))
11.测试,添加数据

12.在命令行窗口进入 MySQL 界面,查看数据表是否生成成功
select * from app_auth;

13.在项目 form 下目录 app,修改文件 views.py,把数据传送给表单
from django.shortcuts import render, redirect, reverse
from django.views.generic import View
from .forms import Auth, AuthModelForm
from .models import Auth as AuthModel
class Regist(View):
TEMPLATE = 'regist.html'
def get(self, request):
user = AuthModel.objects.filter(pk=1).first()
if user:
form = AuthModelForm(instance=user)
else:
form = AuthModelForm()
return render(request, self.TEMPLATE, {'form': form})
def post(self, request):
# username = request.POST.get('username')
# password = request.POST.get('password')
form = AuthModelForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
form.save()
else:
return render(request, self.TEMPLATE, {'form':form})
return redirect(reverse('regist'))
14.测试,表单中 "用户名" 已经收显示数据,但是 "密码" 没有显示数据

15.在项目 form 下目录 app,修改文件 forms.py,在代码类 AuthModelForm 中 widgets 的 password 添加 render_value 属性
from django import forms
from django.forms import fields
from .models import Auth as AuthModel
class AuthModelForm(forms.ModelForm):
class Meta:
model = AuthModel
fields = ['username', 'password']
exclude = [] # 输入不转成表单字段的 model 字段
field_classes = { # 定义字段的类型,一般会按照 model 的类型自动转换
'username': forms.CharField,
'password': forms.CharField,
}
labels = {
'username': '用户名',
'password': '密码',
}
widgets = {
'username': forms.TextInput(
attrs={'placeholder':'请输入用户名'},
),
'password': forms.PasswordInput(
attrs={'placeholder':'请输入密码'},
render_value=True,
),
}
error_messages = {
'username': {'required': '用户名不可以为空'},
'password': {'min_length': '最少不能低于10个字符'},
}
def clean_username(self):
username = self.cleaned_data.get('username')
if len(username) > 10:
raise forms.ValidationError('用户名最大不能超过10')
return username
class Auth(forms.Form):
username = fields.CharField(
max_length=18,
min_length=3,
required=True,
label="用户名",
widget=forms.TextInput(attrs={'placeholder':'最大不能超过18字符'}),
error_messages={'max_length':'最大不能超过18字符!'}
)
password = fields.CharField(
widget=forms.PasswordInput(attrs={'placeholder':'请输入密码'}),
label="密码",
required=True,
min_length=10,
error_messages={'min_length':'最小不能低于10个字符'}
)
def clean(self):
password = self.cleaned_data.get('password', '')
if not password:
raise forms.ValidationError('密码不可以为空!')
def clean_username(self):
username = self.cleaned_data.get('username', '')
if len(username) > 18:
raise forms.ValidationError('用户名最大不能超过18')
return username
16.测试

17.如果出现错误查找对应问题,可在项目 form 下命令行窗口进入 shell 查看
python manage.py shell
18.查看
from django import froms forms.PasswordInput django.forms.widgets.PasswordInput help(forms.PasswordInput)

posted on 2020-02-07 09:03 herisson_pan 阅读(11) 评论(0) 收藏 举报
浙公网安备 33010602011771号