2-2 django-员工管理系统-用户管理
一:视频【2-13】
https://www.bilibili.com/video/BV1S44y1K7Hd?p=29
2.笔记
3.1 用户列表
insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id) values("韩超","666",23,100.68,"2020-01-11",2,1);
insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id) values("刘东","123",23,100.68,"2010-11-11",1,4);
insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id) values("朱虎飞","999",33,9900.68,"2021-05-11",1,1);
用户列表:
view.py
def user_list(request):
"""用户列表"""
query_set = models.UserInfo.objects.all()
return render(request, 'user_list.html', {'query_set': query_set})
python代码中获取数据库数据:
query_set = models.UserInfo.objects.all()
for obj in queryr_set:
print(obj.name,obj.create_time.strftime(%Y-%m-%d),obj.get_level_dispaly,obj.depart.title)
1.普通内容,直接 obj.name
2.时间内容,obj.create_time.strftime(%Y-%m-%d)
3.model中设置的内容,性别1代表女 2代表男这种,就可以使用 obj.get_xxx_dispaly()
4.如果是连表的内容,obj.depart.title 通过当前表的关联表的名,去获取对应的字段
obj.depart_id 获取的是数据库存测的那个字段
obj.depart.title 根据id自动去关联表中获取哪一行数据depart度睇下
user_list.html
{% extends 'layout.html' %} {% block content %} <div class="container"> <div style="margin-bottom: 10px"> <a class="btn btn-success" href="/user/list"> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> 新建用户 </a> </div> <div class="panel panel-default"> <div class="panel-heading"> <span class="glyphicon glyphicon-th-list" aria-hidden="true"></span> 用户列表 </div> <table class="table table-bordered"> <thead> <tr> <th>ID</th> <th>姓名</th> <th>密码</th> <th>年龄</th> <th>账户余额</th> <th>创建时间</th> <th>性别</th> <th>所属部门</th> <th>操作</th> </tr> </thead> <tbody> {% for user in query_set %} <tr> <th scope="row">{{ user.id }}</th> <td>{{ user.name }}</td> <td>{{ user.pwd }}</td> <td>{{ user.age }}</td> <td>{{ user.account }}</td> <td>{{ user.create_time|date:"Y-m-d" }}</td> <td>{{ user.get_gender_display }}</td> <td>{{ user.depart }}</td> <td> <a href="/user/{{ user.id }}/edit/" class="btn btn-primary btn-xs">编辑</a> <a href="/user/del?id={{ user.id }}" class="btn btn-danger btn-xs">删除</a> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> {% endblock %}
html中不支持带括号的东西
1.普通字段内容,obj.name
2.时间内容,user.create_time|date:"Y-m-d"
3.model中设置的内容,性别1代表女 2代表男这种,就可以使用 obj.get_xxx_dispaly
4.如果是连表的内容,obj.depart.title 通过当前表的关联表的名,去获取对应的字段
3.2 新建用户
新建用户:
-
原始方式理思路:不会采用(本质)【麻烦】
- 用户提交数据没有校验。
- 错误,页面上应该有错误提示。
- 页面上,没一个字段都需要我们重新写一遍。 [OK]
- 关联的数据,手动去获取并展示循环展示在页面。 [OK]
-
-
Form组件(小简便)
-
-
path('user/add/', views.user_add),
views.py
def user_add(request):
"""添加用户"""
if request.method == "GET":
content = {
"gender_choices": models.UserInfo.gender_choice,
"depart_list": models.Department.objects.all()
}
return render(request, 'user_add.html', content)
name = request.POST.get('name')
pwd = request.POST.get('pwd')
age = request.POST.get('age')
account = request.POST.get('account')
create_time = request.POST.get('create_time')
gender = request.POST.get('gender')
depart = request.POST.get('depart')
models.UserInfo.objects.create(name=name, age=age, create_time=create_time,
gender=gender, pwd=pwd, account=account, depart_id=depart)
return redirect('/user/list')
1.gender的值,通过字典传入其中,部门也是一样的
user_add.html
{% extends 'layout.html' %} {% block content %} <div class="container"> <div class="panel panel-default form-group"> <div class="panel-heading"> <h3 class="panel-title">新建用户</h3> </div> <div class="panel-body"> <form method="post"> {% csrf_token %} <div class="form-group"> <label >姓名</label> <input type="text" class="form-control" placeholder="姓名" name="name"> </div> <div class="form-group"> <label >密码</label> <input type="text" class="form-control" placeholder="密码" name="pwd"> </div> <div class="form-group"> <label >年龄</label> <input type="text" class="form-control" placeholder="年龄" name="age"> </div> <div class="form-group"> <label >账户余额</label> <input type="text" class="form-control" placeholder="账户余额" name="account"> </div> <div class="form-group"> <label >创建时间</label> <input type="text" class="form-control" placeholder="创建时间" name="create_time"> </div> <div class="form-group"> <label >性别</label> <select class="form-control" name="gender"> {% for item in gender_choices %} <option value="{{ item.0 }}">{{ item.1 }}</option> {% endfor %} </select> </div> <div class="form-group"> <label >部门</label> <select class="form-control" name="depart"> {% for item in depart_list %} <option value="{{ item.id }}">{{ item.title }}</option> {% endfor %} </select> </div> <button type="submit" class="btn btn-primary">提 交</button> </form> </div> </form> </div> </div> </div> {% endblock %}
1.内部的值,可以通过view.py中传递值到html中
2.select 和其他标签,如果想要在最后有值,需要加name才可以
原始方法缺点:
1.输入的数据没有校验
2.错误数据没有错误提示
3.html中需要弄每一个标签值,views中需要获取每一个输入的值
4.html中每个标签关联的值无法获取,需要传入
Form方法【可以解决1,2,3的方法】
1.需要在view.py中定义数据类型定义,不仅仅model中有,这边也需要有。
2.使用的时候需要实例化
3.html使用的时候,会自动生成标签
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})
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>
ModelForm方法【推荐】
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)
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})
user_add.py
<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>
代码:
models.py
from django.db import models
class Department(models.Model):
title = models.CharField(verbose_name='部门名称', max_length=64)
def __str__(self):
return self.title
class UserInfo(models.Model):
name = models.CharField(verbose_name='用户名', max_length=32)
pwd = models.CharField(verbose_name='密码', max_length=32)
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,verbose_name='部门')
gender_choice = [(1, '男'), (2, '女')]
gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choice)
views.py
from django import forms class MyForm(forms.ModelForm): class Meta: model = models.UserInfo fields = ['name', 'age', 'pwd', 'create_time', 'gender', 'account', 'depart'] # widgets = { # "name": forms.TextInput(attrs={"class": "form-control"}), # "pwd": forms.PasswordInput(attrs={"class": "form-control"}) # } # 循环找到所有的插件,添加了class="form-control" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) for name, field in self.fields.items(): field.widget.attrs = {"class": "form-control","placeholder": field.label} def user_model_form_add(request): """ModelFormAdd""" if request.method == "GET": form = MyForm() return render(request, 'user_model_form_add.html', {"form": form}) form = MyForm(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 form-group"> <div class="panel-heading"> <h3 class="panel-title">新建用户</h3> </div> <div class="panel-body"> <form method="post" novalidate> {% csrf_token %} {% for user in form %} <div class="form-group"> <label >{{ user.label }}</label> {{ user }} <span style="color: red;">{{ user.errors.0 }}</span> </div> {% endfor %} <button type="submit" class="btn btn-primary">提 交</button> </form> </div> </form> </div> </div> </div> {% endblock %}
注意:
1.如果想页面展示中文名,需要在models中加 verbose_name='用户名',在html中使用xxx.label来获取
2.如果先页面有自己的样式,可以在view中配置。
方式一:【需要手动一个一个敲】
# 在ModelFrom中的 class Meta中
# widgets = {
# "name": forms.TextInput(attrs={"class": "form-control"}),
# "pwd": forms.PasswordInput(attrs={"class": "form-control"})
# }
为每一个参数添加样式
方式二:【推荐】# 在class Myform类下重写一下__init__函数
# 循环找到所有的插件,添加了class="form-control"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for name, field in self.fields.items():
field.widget.attrs = {"class": "form-control","placeholder": field.label}
if name == "pwd": # 如果不想所有样式一样,可以这样过滤
continue
3.如果想把浏览器的自己校验关闭,就在Html中的form提交报单标签,添加novalidate
-
-
编辑页面(默认数据,根据ID获取并设置到页面中)
-
提交:
-
错误提示
-
数据校验
-
-
url.py
path('user/<int:id>/edit/', views.user_edit),
view.py
def user_edit(request, id):
"""ModelForm edit"""
one_info = models.UserInfo.objects.filter(id=id).first()
if request.method == "GET":
# 根据ID去数据库获取要编辑的那一行数据[对象]
form = MyForm(instance=one_info)
return render(request, 'user_edit.html', {"form": form})
form = MyForm(data=request.POST, instance=one_info)
if form.is_valid():
# 默认保存的是用户输入的所有数据,如果想要再用户输入以外增加一点值
# form.instance.字段名 = 值
form.save()
return redirect('/user/list/')
# 校验失败(在页面上显示错误信息)
return render(request, 'user_model_form_add.html', {"form": form})
如果需要回显存在的内容,需要添加 instance=查询对象,编辑保存的时候也是一样的
如果想编辑添加额外的值,需要额外填写
edit.html 【与添加一样,无变化】
{% extends 'layout.html' %} {% block content %} <div class="container"> <div class="panel panel-default form-group"> <div class="panel-heading"> <h3 class="panel-title">编辑用户</h3> </div> <div class="panel-body"> <form method="post" novalidate> {% csrf_token %} {% for user in form %} <div class="form-group"> <label >{{ user.label }}</label> {{ user }} <span style="color: red;">{{ user.errors.0 }}</span> </div> {% endfor %} <button type="submit" class="btn btn-primary">提 交</button> </form> </div> </form> </div> </div> </div> {% endblock %}
3.4 删除
删除用户可以在url上传递id,也可以在get请求的参数中添加
url.py
path('user/del/', views.user_del),
views.py
def user_del(request):
# 删除
id = request.GET.get('id')
models.UserInfo.objects.filter(id=id).delete()
return redirect('/user/list/')
user_list.html
<a href="/user/{{ user.id }}/edit/" class="btn btn-primary btn-xs">编辑</a> <a href="/user/del?id={{ user.id }}" class="btn btn-danger btn-xs">删除</a>