Python实现员工管理系统(Django页面版 ) 三
在前两个小节中我们实现了部门页面和员工页面的代码逻辑,其中对于数据库的使用我们都是在model.py 模块里面进行建立,接下来我将为大家介绍一种新的一种方式----ModelFrom。
ModelFrom介绍
ModelForm是Django中的一个表单类,它可以根据一个模型类自动生成对应的表单。使用ModelForm可以大大简化表单的创建和验证工作。
传统方式:
1、用户提交数据没有校验
2、页面没有错误提示
3、数据库字段很多的情况下,每个字段都要手写
4、关联数据,手动获取
ModelFrom可以充分的解决这些问题,下面我将重写员工页面的代码逻辑,带领大家引入其魅力。
将各组件方法进行分组归类:
我们之间在给各个组件方法代码进行编写的时候,都是在view.py里面进行编写的,这样做其实并不太好对于后期代码的维护,不方便程序员进行查阅,因此我们可以在我们app文件下创建一个views文件夹用于存放我们的各个组件方法。

在其中建立两个python文件,分别用于存放员工组件方法以及部门组件方法

在views.py文件中分别将这两个组件方法分别导入到上面两个py文件中。


在urls里面重新配置组件方法地址
原来的urls:

更改后的urls:
首先需要导入views文件夹,将其中的各个模块引入,最后只需要借用这些模块就可以调用各个组件的方法。


全部更改完成之后下面我们开始重写员工表的各组件方法。
员工信息添加-----ModelForm版本
我们在原来的员工信息中输入信息时我们可以发现,只要我们输入的和model模块里面建立字段保持一致,那我们就可以将这个信息添加进来,但是这样对于实际开发中是不可取的,因为对于部分字段我们需要添加一些约束。
例如我们添加一下信息:

我们可以发现这些信息是可以直接添加进来的,但是我们又希望里面会给我们提供一些约束,当不满足这些约束的时候信息是不能添加进来的,这个时候有小伙伴可能会想,我在做添加信息组件方法时我加入条件判断对我需要字段进行约束不就可以了吗。这样做的方法是可行的,但是不够好。对于字段比较多的时候,我们不能对每一个字段进行一个约束,这样会让我们的代码看上去冗余。因此我们接下来引入ModelFrom来进行这方法的重写。
创建UserModelForm类
class UserModelForm(forms.ModelForm):
# 对于 name 字段进行重写
name = forms.CharField(min_length=2, label='姓名')
# 硬性规定写法
class Meta:
# 数据库的导入
model = models.UserInfo
# __all__ 代表所有字段
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for title, field in self.fields.items():
field.widget.attrs = {'class': 'form-control'}
对于 name 字段:

我们可以从之前在model.py里面的name字段可以看出,之前我们规定的是最大字长为64,但是现在我们想要用户输入的姓名最少也得是2个字,因此我们在UserModelForm类里面对name字段进行一个重写。
对于 Meta类,我们在里面添加我们的数据库以及数据库里面的所有字段。
在这里的字段是由字段名和输入框组成的,如果我们后续需要对输入框的样式进行更改,我们仅需要获取这个字段输入框,然后在里面添加样式方法即可

最后如果我们想要更改输入框的样式,我们就可以使用field.widget.attrs = {'class': 'form-control'}方法直接添加类属性即可。
添加信息组件方法
下面我们来编写ModelFrom版本的信息添加方法:
首先我们先写html页面展示:
对于前面的html页面我们可以发现其实添加和修改的页面差不多都是一致的,只是其中的字段不一样而已,所以只要我们能够获取到所以的字段,我们是不是可以直接将这些字段传入到我们的前端页面进行一个展示即可,这就关联到我们刚刚写的UserModelForm类了。
public_add-modify.html:
{% extends "layout.html" %}
{% block content %}
<div class="container">
<div class="panel panel-info">
<div class="panel-heading">
{# 操作名称#}
<h3 class="panel-title">{{ title }}</h3>
</div>
<div class="panel-body">
<form method="post">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
{# field.label :字段名#}
<label for="inputEmail3" class="col-sm-2 control-label">{{ field.label }}</label>
{# field:input标签#}
{{ field }}
{# field.errors:错误展示#}
<span style="color: red">{{ field.errors.0 }}</span>
{# <input type="text" class="form-control" id="inputEmail3" placeholder="姓名" name="name">#}
</div>
{% endfor %}
<button type="submit" class="btn btn-success">提交</button>
</form>
</div>
</div>
</div>
{% endblock %}
前端页面代码编写完成之后下面我们开始构建添加组件代码。
user.py
def user_model_form_add(request):
title = '添加员工信息'
if request.method == 'GET':
# form代表获取所有字段信息
form = UserModelForm()
return render(request,'public_add-modify.html',{'form':form,'title':title})
# data=request.POST 写入这个参数代表提交信息
form = UserModelForm(data=request.POST)
# 判断数据是否存在问题
if form.is_valid():
# 保存信息
form.save()
return redirect('/user/list')
# 如果存在问题则返回到添加页面重新添加,且会附带错误提示信息
return render(request,'public_add-modify.html',{'form':form,'title':title})
添加方法写完之后接下来我们需要配置我们的路由(URL):
urls:

最后别忘记在员工信息添加页面再添加一个按钮用于存放ModelFrom版本添加员工信息的超链接
url_list.html

最后我们开启服务,展示效果如下:

接下来我们重新输入刚刚的信息进行插入,提交后我们发现出现了报错信息提示

修改信息后我们重新添加

这样我们成功实现了员工添加信息的ModelForm版本
员工信息修改----ModelForm版本
员工信息修改的ModelForm版本其实与员工信息添加的ModelForm版本差不多,只是有部分需要注意,同时员工信息修改是通过员工的ID进行定位修改的。
user.py
def user_modify(request,nid):
title = '修改员工信息'
obj = models.UserInfo.objects.filter(id=nid).first()
if request.method == 'GET':
form = UserModelForm(instance=obj)
return render(request,'public_add-modify.html', {'form':form,'title':title})
# instance加入form才知道这个是修改操作,否者就会进行添加操作
form = UserModelForm(data=request.POST,instance=obj)
if form.is_valid():
form.save()
return redirect('/user/list')
return render(request,'public_add-modify.html', {'form':form,'title':title})
其中需要注意的是 instance 参数,它是用来做修改操作的依据,如果没有这个参数,那么它会将你提交的参数作为添加数据到数据库中,这也是和添加时的不同。同时它会在你进行get请求时将数据copy到post请求页面中。

由此我们可以看出,在我对王五那个数据进行修改时,王五之前的数据也会出现在上面,这也是instance参数中的一个作用。
本篇博文内容不多,只是为大家引入一下ModelForm这个概念,如果大家有哪里不清楚或者发现文中出现问题,欢迎大家提出 。