文章目录
员工管理系统
1. 新建项目
2. 创建App
python manage.py startapp app01
相当于自动运行了一个manage.py
记得注册app,新版会自动注册
3. 设计表结构 (django)
from django.db import models
class Department(models.Model):
""" 部门表 """
title = models.CharField(verbose_name='标题', max_length=32)
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_id = models.BigIntegerField(verbose_name='部门ID')
# 1.有约束
# - to, 与哪张表关联
# - to_field, 与哪一列关联
# 2.Django自动
# - 写的depart
# - 生成数据列 depart_id
# 3. 部门表被删除
# - 3.1 级联删除 on_delete=models.CASCADE
# - 3.2 置空 null=True, blank=True, on_delete=models.SET_NULL
depart = models.ForeignKey(to='Department', to_field='id', verbose_name='部门ID', on_delete=models.CASCADE)
gender_choices = (
(1, '男'),
(2, '女'),
)
gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices)
4. MySQL中生成表
- 工具连接MySQL生成数据库
create database django_2 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
- 修改配置文件
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": "django_2",
"USER": "root",
"PASSWORD": "123",
"HOST": "127.0.0.1",
"PORT": 3306,
}
}
- 通过django命令生成表
python manage.py makemigrations
python manage.py migrate
5. 静态文件管理
6. 部门的管理
先体验一下最原始的方法做。
Django中还提供了Form和ModelForm组件(方便)
我们后面做的这些有一个新知识点,在发送post请求时
我们在url.py中写上这个 /depart/int:nid/edit/ 中间多加一个,表示我们会传递一个int的参数nid,和后面问号大致差不多,但是更方便
views.py
from django.shortcuts import render, redirect
from app01 import models
def depart_list(request):
""" 部门列表 """
# 1.去数据库中获取所有的部门列表
dep_list = models.Department.objects.all()
return render(request, "depart_list.html", {"dep_list": dep_list})
def depart_add(request):
if request.method == "GET":
return render(request, "depart_add.html")
# 获取用户POST提交过来的数据(title输入为空暂不考虑)
title = request.POST.get("title")
# 保存到数据库
models.Department.objects.create(title=title)
# 重定向回部门列表
return redirect("/depart/list/")
def depart_delete(request):
"""删除部门"""
# 获取id
nid = request.GET.get('nid')
# 删除
models.Department.objects.filter(id=nid).delete()
# 跳转回部门列表
return redirect("/depart/list/")
def depart_edit(request, nid):
"""编辑部门"""
if request.method == "GET":
# 根据nid,获取数据
row_obj = models.Department.objects.filter(id=nid).first()
return render(request, "depart_edit.html", {"row_obj": row_obj})
# 获取用户提交的标题
title = request.POST.get("title")
# 根据id找到数据库中的数据并进行更新
models.Department.objects.filter(id=nid).update(title=title)
# 重定向回部门列表
return redirect("/depart/list/")
6.1 部门列表
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>部门列表</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
<style>
.navbar {
border-radius: 0;
}
</style>
</head>
<body>
<nav class="navbar navbar-default">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<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><a href="/depart/list/"> 部门管理 </a></li>
<li><a href="#">Link</a></li>
</ul>
<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">高宇轩 <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>
<div class="container">
<div>
<a class="btn btn-success" style="margin-bottom: 20px" href="/depart/add/">新建部门</a>
</div>
<div class="bs-example" data-example-id="panel-without-body-with-table">
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">
<span class="glyphicon glyphicon-list" aria-hidden="true"></span>
部门列表
</div>
<!-- Table -->
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>名称</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for dep in dep_list %}
<tr>
<th scope="row">{{ dep.id }}</th>
<td>{{ dep.title }}</td>
<td>
<a class="btn btn-primary btn-xs" href="/depart/{{ dep.id }}/edit/">编辑</a>
<a class="btn btn-danger btn-xs" href="/depart/delete/?nid={{ dep.id }}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="{% static 'js/jquery-3.7.1.min.js' %}"></script>
<script type="text/javascript" src="{% static 'plugins/bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
</body>
</html>
6.2 新增部门
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加部门</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
<style>
.navbar {
border-radius: 0;
}
</style>
</head>
<body>
<nav class="navbar navbar-default">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<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><a href="/depart/list/"> 部门管理 </a></li>
<li><a href="#">Link</a></li>
</ul>
<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">高宇轩 <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>
<div class="container" style="margin-top: 20px">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"> 新建部门 </h3>
</div>
<div class="panel-body">
<form method="post">
{% csrf_token %}
<div class="form-group">
<label class="col-sm-2 control-label">标题</label>
<input type="text" class="form-control" placeholder="标题" name="title">
</div>
<button type="submit" class="btn btn-primary">保 存</button>
</form>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="{% static 'js/jquery-3.7.1.min.js' %}"></script>
<script type="text/javascript" src="{% static 'plugins/bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
</body>
</html>
6.3 编辑部门
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编辑部门</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
<style>
.navbar {
border-radius: 0;
}
</style>
</head>
<body>
<nav class="navbar navbar-default">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<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><a href="/depart/list/"> 部门管理 </a></li>
<li><a href="#">Link</a></li>
</ul>
<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">高宇轩 <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>
<div class="container" style="margin-top: 20px">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"> 编辑部门 </h3>
</div>
<div class="panel-body">
<form method="post">
{% csrf_token %}
<div class="form-group">
<label class="col-sm-2 control-label">标题</label>
<input type="text" class="form-control" placeholder="标题" name="title"
value="{{ row_obj.title }}">
</div>
<button type="submit" class="btn btn-primary">保 存</button>
</form>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="{% static 'js/jquery-3.7.1.min.js' %}"></script>
<script type="text/javascript" src="{% static 'plugins/bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
</body>
</html>
7. 模板的继承
定义模板:
{% 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-dist/css/bootstrap.min.css' %}">
{% block css %}{% endblock %}
</head>
<body>
<h1>标题</h1>
<div>
{% block content %}
{% endblock %}
</div>
<h1>尾部</h1>
</body>
<script type="text/javascript" src="{% static 'js/jquery-3.7.1.min.js' %}"></script>
<script type="text/javascript" src="{% static 'plugins/bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
</html>
继承模板:
{% extends 'layout.html' %}
{% block content %}
<h1>内容</h1>
{% endblock %}
8. 用户管理
模板语法不加括号
python语法中读取性别user.get_gender_display()
但在模板中要去掉括号,如果需要加括号,模板会自动帮你加
python中时间转换为字符串user.create_time.strftime('%Y-%m-%d')
模板中user.create_time|date:'%Y-%m-%d'
新建用户:
-
原始方法(本质,较为麻烦)
- 用户提交的数据没有校验 - 如果出现错误,页面应该有错误提示 - 页面上,每一个字段都需要我们重新写一遍。 - 有关联数据需要手动获取并循环展示在页面中
-
Django组件
- Form组件 (前三个+一些代码)
- ModelForm组件(最方便)
8.1 初识Form
1. views.py
class MyForm(Form):
user = forms.CharField(widget=form.Input) # Form的字段
pwd = forms.CharField(form.Input)
email = forms.CharField(form.Input)
def user_add(request):
if request.menthod == "GET":
form = MyForm() # 实例化一个MyForm对象
return render(request, "user_add.html", {"form": form})
2. user_add.html
<form method="post">
{{ form.user }}
{{ form.pwd }}
{{ form.email }}
<!-- <input type="text" class="form-control" placeholder="姓名" name="name"> -->
</form>
<form method="post">
{% for field in form %}
{{ field }}
{% endfor %}
<!-- <input type="text" class="form-control" placeholder="姓名" name="name"> -->
</form>
8.2 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', verbose_name='部门ID', on_delete=models.CASCADE)
gender_choices = (
(1, '男'),
(2, '女'),
)
gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices)
1. views.py
class MyForm(ModelForm):
class Meta:
model = UserInfo
field = ["name", "password", "age"]
def user_add(request):
if request.menthod == "GET":
form = MyForm() # 实例化一个MyForm对象
return render(request, "user_add.html", {"form": form})
2. user_add.html
<form method="post">
{{ form.user.label }}{{ form.user }}
{{ form.pwd }}
{{ form.email }}
<!-- <input type="text" class="form-control" placeholder="姓名" name="name"> -->
</form>
<form method="post">
{% for field in form %}
{{ field }}
{% endfor %}
<!-- <input type="text" class="form-control" placeholder="姓名" name="name"> -->
</form>
案例
from django import forms
class UserModelForm(forms.ModelForm):
name = forms.CharField(min_length=2, max_length=20, label="用户名")
class Meta:
model = models.UserInfo
fields = ['name', 'password', 'age', 'create_time', 'gender', 'depart']
# widgets = {
# 'name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': ''})
# }
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环找到所有的插件,添加class="form-control"
for name, field in self.fields.items():
field.widget.attrs = {"class": "form-control", "placeholder": field.label}
def user_modelform_add(request):
"""基于modelform添加用户"""
form = UserModelForm()
if request.method == "GET":
return render(request, "user_modelform_add.html", {"form": form})
# 用户POST提交数据,数据校验
form = UserModelForm(data=request.POST)
if form.is_valid():
print(form.cleaned_data)
form.save() # 自动保存
return redirect("/user/list/")
else:
return render(request, "user_modelform_add.html", {"form": form})
{% extends "layout.html" %}
{% block content %}
<div class="container" style="margin-top: 20px">
<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 class="col-sm-2 control-label">{{ field.label }}</label>
<!-- <input type="text" class="form-control" placeholder="姓名" name="name"> -->
{{ field }}
<span style="color: red">{{ field.errors.0 }}</span>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">提 交</button>
</form>
</div>
</div>
</div>
{% endblock %}
8.3 编辑用户
-
点击编辑,跳转到编辑页面(将要编辑的ID携带过去)
-
编辑页面(默认数据,根据ID获取)
-
提交:
-
错误提示
-
数据校验
-
在数据库更新
-
加上这个就能显示默认值
form = UserModelForm(instance=row_object)
user_edit.py
def user_edit(request, nid):
"""编辑用户"""
row_object = models.UserInfo.objects.filter(id=nid).first()
# 根据ID获取数据库该行数据(对象)
if request.method == "GET":
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.save()
return redirect("/user/list/")
return render(request, "user_edit.html", {"form": form})
user_delete.py
def user_delete(request, nid):
models.UserInfo.objects.filter(id=nid).delete()
return redirect("/user/list/")