1、models.py
from django.db import models
# Create your models here.
class Department(models.Model):
'''部门表'''
title = models.CharField(verbose_name='标签',max_length=32)
# 实例化对象用print输出时是一个对象,__str__(self) 可以打印具体的属性
def __str__(self):
return self.title
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 decimal(10,2) 小数
account = models.DecimalField(verbose_name="账户余额",max_digits=10,decimal_places=2,default=0)
# create_time = models.DateTimeField(verbose_name="入职时间")
create_time = models.DateField(verbose_name="入职时间")
# depart_id 为外键,连接Department表中的id
# - to,与哪张表关联
# - to_field,表中的哪一列关联
# on_delete=models.CASCADE() 表示删除时级联
# 2.django自动
# - 写的depart
# - 生成数据列 depart_id
# 3.部门表被删除
# ### 3.1 级联删除
depart = models.ForeignKey(verbose_name="部门",to="Department",to_field="id",on_delete=models.CASCADE)
# ### 3.2 on_delete=models.SET_NULL 表示删除时置空
# depart = models.ForeignKey(to="Department",to_field="id",null=True,blank=True,on_delete=models.SET_NULL)
# 在django中做的约束
gender_choices = (
(1,"男"),
(2,"女"),
)
gender = models.SmallIntegerField(verbose_name="性别",choices=gender_choices)
# level_choices = (
# (1, "0级"),
# (2, "1级"),
# )
# level = models.SmallIntegerField(verbose_name="级别",choices=level_choices)
2、urls.py
from django.contrib import admin
from django.urls import path
from my_app import views
urlpatterns = [
path('user/list/', views.user_list),
path('user/add/', views.user_add),
path('user/model/form/add/', views.user_model_form_add),
path('user/del/', views.user_del),
path('user/<int:uid>/up/', views.user_up), # 访问形式:http://127.0.0.1:8000/user/1/up/
path('user/<int:uid>/edit/', views.user_edit), # 访问形式:http://127.0.0.1:8000/user/1/edit/
]
3、views.py
# 用户列表
def user_list(request):
userLists = models.UserInfo.objects.all()
for user in userLists:
# 性别是元组:(1,"男"),(2,"女") user.gender为数字
# user.get_gender_display()为数字对应的属性 user.get_字段属性_display()
# user.create_time.strftime("%Y-%m-%d") 将datetime类型转换为字符串类型
print(user.id,user.name,user.password,user.age,user.account,user.create_time.strftime("%Y-%m-%d"),user.get_gender_display(),user.depart.title)
user.depart_id # 获取数据库中存储的那个字段值
user.depart # 根据id自动去关联的表中获取那一行数据depart对象。
# print(user.depart_id,user.depart.title)
return render(request,"user_list.html",{"user_list":userLists})
# 删除用户
def user_del(request):
user_id = request.GET.get("id")
models.UserInfo.objects.filter(id=user_id).delete()
return redirect("/user/list/")
# ************* ModelForm 示例 *************
# from django import forms
class DateInput(forms.DateInput):
input_type = 'date'
class UserModelForm(forms.ModelForm):
# 对字段属性加限制条件
name = forms.CharField(min_length=2,label="姓名") # 限制条件:至少输入2个字符
# create_time = forms.DateTimeField(label="入职时间") # 限制条件:必须是时间格式
# validators 正则表达式:密码至少包含 数字和英文,长度6-20 validators="^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$"
# password = forms.CharField(label="密码")
class Meta:
model = models.UserInfo
fields = ["name","password","age","account","create_time","gender","depart"]
# widgets = { # 加css样式
# # "name": forms.TextInput(attrs={"class": "form-control"}),
# "password": forms.PasswordInput(attrs={"class": "form-control","placeholder": "密码"}),
# # "age": forms.TextInput(attrs={"class": "form-control"}),
# "create_time": DateInput(attrs={"class": "form-control dt"}),
#
# }
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环找到所有的插件,添加了class="form-control"
for name,field in self.fields.items():
# if name == "password":
# continue
# if name == "create_time" or name == "password":
# continue
# # 多添加一个id属性
# # field.widget.attrs = {"class": "form-control dt", "placeholder": field.label}
# else:
# field.widget.attrs = {"class": "form-control", "placeholder": field.label}
field.widget.attrs = {"class": "form-control", "placeholder": field.label}
# 添加用户ModelForm
def user_model_form_add(request):
''' 添加用户ModelForm '''
req_method = request.method
if req_method == 'GET':
form = UserModelForm()
return render(request, "user_model_form_add.html", {"form": form})
# 用户POST提交数据,数据校验
form = UserModelForm(data=request.POST)
if form.is_valid(): # 数据校验成功
# 如果数据合法,就存到数据库
print(form.cleaned_data) # {'name': '333', 'password': '333', 'age': 33, 'account': Decimal('333'), 'create_time': datetime.datetime(2021, 11, 11, 0, 0, tzinfo=<UTC>), 'gender': 1, 'depart': <Department: 编辑部门>}
# models.UserInfo.objects.create(...) # 把数据存到数据库中 方式1
# 方式2(推荐)
form.save() # 直接将数据存储到数据库
return redirect("/user/list/")
# 数据校验失败
# else:
# print(form.errors) 数据校验错误信息
return render(request, "user_model_form_add.html", {"form": form})
# 更新用户(ModelForm格式)
def user_edit(request,uid):
req_method = request.method
# 根据id获取数据对象
user = models.UserInfo.objects.filter(id=uid).first()
if req_method == 'GET':
form = UserModelForm(instance=user)
return render(request, "user_model_form_edit.html", {"form": form})
# data是从页面传过来的更新数据,instance表示要更新的那个数据
form = UserModelForm(data=request.POST,instance=user)
# 数据校验
if form.is_valid():
# form.save() 默认保存的是用户输入的所有数据
# 如果想除了保存用户输入的值之外,再添加其他值 用 form.instance.字段名 = 值
# form.instance.password = "123456"
form.save() # 直接将数据存储到数据库
return redirect("/user/list/")
# 数据校验失败
return render(request,"user_model_form_edit.html",{"form": form})
4、layout.html (模板)
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'plugins/font-awesome-4.7.0/css/font-awesome.css' %}">
<link rel="stylesheet" href="{% static 'plugins/bootstrap-datepicker/css/bootstrap-datepicker.css' %}">
<style>
.navbar {
border-radius: 0;
}
</style>
{% block css %}{% endblock %}
</head>
<body>
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">用户管理系统</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
{# <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>#}
<li><a href="/depart/list/">部门管理</a></li>
<li><a href="/user/list/">用户管理</a></li>
<li><a href="#">Link</a></li>
{# <li class="dropdown">#}
{# <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"#}
{# aria-expanded="false">Dropdown <span class="caret"></span></a>#}
{# <ul class="dropdown-menu">#}
{# <li><a href="#">Action</a></li>#}
{# <li><a href="#">Another action</a></li>#}
{# <li><a href="#">Something else here</a></li>#}
{# <li role="separator" class="divider"></li>#}
{# <li><a href="#">Separated link</a></li>#}
{# <li role="separator" class="divider"></li>#}
{# <li><a href="#">One more separated link</a></li>#}
{# </ul>#}
{# </li>#}
</ul>
{# <form class="navbar-form navbar-left">#}
{# <div class="form-group">#}
{# <input type="text" class="form-control" placeholder="Search">#}
{# </div>#}
{# <button type="submit" class="btn btn-default">Submit</button>#}
{# </form>#}
<ul class="nav navbar-nav navbar-right">
<li><a href="#">登录</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">lc <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">个人资料</a></li>
<li><a href="#">我的信息</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">注销</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<div>
{% block content %} {% endblock %}
</div>
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
{% block js %}{% endblock %}
</body>
</html>
5、user_list.html
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div style="margin-bottom: 10px;">
{# <a class="btn btn-success" href="#" target="_blank"> <!-- 在新的页面打开 -->#}
<a class="btn btn-success" href="/user/add/">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
新建用户
</a>
<a class="btn btn-success" href="/user/model/form/add/">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
新建用户ModelForm
</a>
</div>
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">
<span class="glyphicon glyphicon-th-list" aria-hidden="true"></span> 用户列表
</div>
<!-- Table -->
<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 user_list %}
<tr>
<th scope="row">{{ user.id }}</th>
<td>{{ user.name }}</td>
<td>{{ user.password }}</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.title }}</td>
<td>
<a href="/user/{{ user.id }}/edit/" class="btn btn-primary btn-xs">编辑</a>
{# <a href="/user/{{ user.id }}/up/" class="btn btn-primary btn-xs">编辑</a>#}
{# <a href="/user/up/?id={{ user.id }}" 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>
{% endblock %}
6、user_model_form_add.html
{% extends 'layout.html' %}
{% load static %}
{% 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 href="/user/model/form/add/" method="post" novalidate> <!-- novalidate把游览器的校验关闭 -->
<!--不加会报错,这是django的校验-->
{% csrf_token %}
{% for field in form %}
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>{{ field.label }}</label>
{{ field }}
<!--表示只显示第一个错误: field.errors.0 -->
<span style="color: red;">{{ field.errors.0 }}</span>
</div>
</div>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">提 交</button>
</form>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script src="{% static 'plugins/bootstrap-datepicker/js/bootstrap-datepicker.js' %}"></script>
<script src="{% static 'plugins/bootstrap-datepicker/locales/bootstrap-datepicker.zh-CN.min.js' %}"></script>
{# <script src="static/plugins/bootstrap-datepicker/js/bootstrap-datepicker.js"></script>#}
{# <script src="static/plugins/bootstrap-datepicker/locales/bootstrap-datepicker.zh-CN.min.js"></script>#}
<script type="text/javascript">
$(function () {
$('.dt').datepicker({
format: 'yyyy-mm-dd',
// startDate: '0', // 表示开始时间从当前时间开始
language: "zh-CN",
autoclose: true
});
});
</script>
{% endblock %}
{#<!DOCTYPE html>#}
{#<html lang="en">#}
{#<head>#}
{# <meta charset="UTF-8">#}
{# <title>Title</title>#}
{##}
{##}
{#</head>#}
{#<body>#}
{##}
{#<form method="post">#}
{# {% for field in form %}#}
{# {{ field.label }} : {{ field }}#}
{# {% endfor %}#}
{#</form>#}
{#</body>#}
{#</html>#}
7、user_model_form_edit.html
{% extends 'layout.html' %}
{% load static %}
{% 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> <!-- novalidate把游览器的校验关闭 -->
<!--不加会报错,这是django的校验-->
{% csrf_token %}
{% for field in form %}
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>{{ field.label }}</label>
{{ field }}
<!--表示只显示第一个错误: field.errors.0 -->
<span style="color: red;">{{ field.errors.0 }}</span>
</div>
</div>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">提 交</button>
</form>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script src="{% static 'plugins/bootstrap-datepicker/js/bootstrap-datepicker.js' %}"></script>
<script src="{% static 'plugins/bootstrap-datepicker/locales/bootstrap-datepicker.zh-CN.min.js' %}"></script>
{# <script src="static/plugins/bootstrap-datepicker/js/bootstrap-datepicker.js"></script>#}
{# <script src="static/plugins/bootstrap-datepicker/locales/bootstrap-datepicker.zh-CN.min.js"></script>#}
<script type="text/javascript">
$(function () {
$('.dt').datepicker({
format: 'yyyy-mm-dd',
// startDate: '0', // 表示开始时间从当前时间开始
language: "zh-CN",
autoclose: true
});
});
</script>
{% endblock %}
8、效果图