Django中form和modelform学习
1 初识Form
当我们需要对注册界面或者登陆界面等,需要我们填写信息的网页进行校验时,即填写内容不能为空,如果按之前的方式我们需要写好多if..else语句来实现字段校验,这是不方便的,由此我们可以引出form和modelform
1. views.py
class MyForm(Form):
user = forms.CharField(widget=forms.Input)
pwd = form.CharFiled(widget=forms.Input)
email = form.CharFiled(widget=forms.Input)
account = form.CharFiled(widget=forms.Input)
create_time = form.CharFiled(widget=forms.Input)
depart = form.CharFiled(widget=forms.Input)
gender = form.CharFiled(widget=forms.Input)
def user_add(request):
if request.method == "GET":
form = MyForm()
return render(request, 'user_add.html',{"form":form})
2.user_add.html
<form method="post">
{% for field in form%}
{{ field }}
{% endfor %}
<!-- <input type="text" placeholder="姓名" name="user" /> -->
</form>
<form method="post">
{{ form.user }}
{{ form.pwd }}
{{ form.email }}
<!-- <input type="text" placeholder="姓名" name="user" /> -->
</form>
如上将可以在html页面自动生成输入框,而如果引入很多字段需要在myform里需要写很多
由此引出modelform
3 ModelForm(推荐)
0. models.py
class UserInfo(models.Model):
""" 员工表 """
name = models.CharField(verbose_name="姓名", max_length=16)
password = models.CharField(verbose_name="密码", max_length=64)
age = models.IntegerField(verbose_name="年龄")
account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
create_time = models.DateTimeField(verbose_name="入职时间")
depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)
gender_choices = (
(1, "男"),
(2, "女"),
)
gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
1. views.py
class MyForm(ModelForm):
xx = form.CharField*("...")#新加不在数据库中的字段
class Meta:
model = UserInfo
fields = ["name","password","age","xx"]#选择需要的字段即可
def user_add(request):
if request.method == "GET":
form = MyForm()
return render(request, 'user_add.html',{"form":form})
2.user_add.html
<form method="post">
{% for field in form%}
{{ field }}
{% endfor %}
<!-- <input type="text" placeholder="姓名" name="user" /> -->
</form>
<form method="post">
{{ form.user }}
{{ form.pwd }}
{{ form.email }}
<!-- <input type="text" placeholder="姓名" name="user" /> -->
</form>
引入外键表时:
写上部分depart时,返回的是一个个对象,没有读到里面的title,这时候需要用面向对象知识里学到的
#__str__()函数
class Department(models.Model):
""" 部门表 """
title = models.CharField(verbose_name='标题', max_length=32)
def __str__(self):
return self.title
#这样返回的才是部门名称
field.label
指的是数据库中的verbose_name,modelform会自动帮我们读取verbose_name,如果没有该参数将读取字段名
需要为自动生成的输入框添加样式
class MyForm(ModelForm):
xx = form.CharField*("...")#新加不在数据库中的字段
class Meta:
model = UserInfo
fields = ["name","password","age","xx"]#选择需要的字段即可
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
for name,field in self.fields.items():
#if name == "password":让某些字段加或者不加
field.widget.attrs={"class":"xx样式","placeholder":field.label}
校验过程
def user_model_form_add(request):
""" 添加用户(ModelForm版本)"""
if request.method == "GET":
form = UserModelForm()
return render(request, 'user_model_form_add.html', {"form": form})
# 用户POST提交数据,数据校验。
form = UserModelForm(data=request.POST)
if form.is_valid():
# 如果数据合法,保存到数据库
# {'name': '123', 'password': '123', 'age': 11, 'account': Decimal('0'), 'create_time': datetime.datetime(2011, 11, 11, 0, 0, tzinfo=<UTC>), 'gender': 1, 'depart': <Department: IT运维部门>}
# print(form.cleaned_data)
# models.UserInfo.objects.create(..)
form.save()#直接用这个即可
return redirect('/user/list/')
# 校验失败(在页面上显示错误信息)
return render(request, 'user_model_form_add.html', {"form": form})
html界面:
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"> 新建用户 </h3>
</div>
<div class="panel-body">
<form method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label>{{ field.label }}</label>
{{ field }}
<span style="color: red;">{{ field.errors.0 }}</span>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">提 交</button>
</form>
</div>
</div>
</div>
{% endblock %}
模板html页面就不放了,读取错误时只读errors.0即可
如果有其他需要做验证的规则,可以在views中
class UserModelForm(forms.ModelForm):
name = forms.CharField(min_length=3, label="用户名")
class Meta:
model = models.UserInfo
fields = ["name", "password", "age", 'account', 'create_time', "gender", "depart"]
# widgets = {
# "name": forms.TextInput(attrs={"class": "form-control"}),
# "password": forms.PasswordInput(attrs={"class": "form-control"}),
# "age": forms.TextInput(attrs={"class": "form-control"}),
# }
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环找到所有的插件,添加了class="form-control"
for name, field in self.fields.items():
# if name == "password":
# continue
field.widget.attrs = {"class": "form-control", "placeholder": field.label}
如上的name中写min_length=3这样去做验证
报错为英文,想要修改为中文
settings中
设置
# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans'
如上
编辑修改功能
主要是要考虑修改当前而非新增用户
def user_edit(request, nid):
""" 编辑用户 """
row_object = models.UserInfo.objects.filter(id=nid).first()
if request.method == "GET":
# 根据ID去数据库获取要编辑的那一行数据(对象)
form = UserModelForm(instance=row_object)
return render(request, 'user_edit.html', {'form': form})
form = UserModelForm(data=request.POST, instance=row_object)
if form.is_valid():
# 默认保存的是用户输入的所有数据,如果想要再用户输入以外增加一点值,即将某些字段设为固定值
# form.instance.字段名 = 值
form.save()
return redirect('/user/list/')
return render(request, 'user_edit.html', {"form": form})
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具