创建app
属于自动执行了python manage.py
直接在里面运行startapp app01就可以创建app01的项目了
之后在setting.py中注册app01
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
'app01.apps.App01Config'
]
创建表
class Department(models.Model):
"""部门表"""
id=models.BigAutoField(verbose_name="ID",primary_key=True)#系统默认自己创建
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)
#10位数字,小数位是2
create_time=models.DateTimeField(verbose_name="入职时间")
#to表示与哪张表相连
#to_fields表示与哪一列相连
#写depart后Django会自动生成depart_id
#on_delete=models.CASCADE级联删除
#置空删除on_delete=models.SET_NULL
depart=models.ForeignKey(to="Department",to_field="id",on_delete=models.CASCADE)
其中用户中加入部门数据,如果是正常开始用ID,对于特别大的公司用字符串名称,这样可以防止连表的时间消耗,属于用空间换时间。
部门列表
###前端页面
{% 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' %}">
<style>
.navbar{
border-radius: 0;
}
</style>
</head>
<body>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- 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>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="#">Link</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<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>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<srcipt src="{% static 'js/jquery-3.6.0.min.js' %}"></srcipt>
<srcipt src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></srcipt>
</body>
</html>
上面的导航栏代码在导航栏代码中找到的,加入后修改成上面的部分,记得最上面加入{% load static %}。
<div>
<div class="container">
<div style = "margin-bottom: 10px">
<a class="btn btn-primary" href="">新建部门</a>
</div>
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">Panel heading</div>
<!-- Table -->
<table class="table table-bordered">
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
新增
在depart_list中增加跳转地址
<a class="btn btn-primary" href="/depart/add/" >
{# target="_blank" 在新的页面产生#}
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
新建部门</a>
新建一个depart_add.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' %}">
<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>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="/depart/list/">部门管理</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><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">注销</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">新建面板</h3>
</div>
<div class="panel-body">
<form>
<div class="form-group">
<label for="exampleInputEmail1">标题</label>
<input type="text" class="form-control" id="exampleInputEmail1" placeholder="标题" name="title">
</div>
<button type="submit" class="btn btn-primary">保存</button>
</form>
</div>
</div>
</div>
<srcipt src="{% static 'js/jquery-3.6.0.min.js' %}"></srcipt>
<srcipt src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></srcipt>
</body>
</html>
在表单中增加post修改的方式
<form method="post">
{% csrf_token %}
<div class="form-group">
<label for="exampleInputEmail1">标题</label>
<input type="text" class="form-control" id="exampleInputEmail1" placeholder="标题" name="title">
</div>
<button type="submit" class="btn btn-primary">保存</button>
</form>
添加后端代码
def depart_add(request):
"'添加部门'"
if request.method=="GET":
return render(request,"depart_add.html")
#获取post中的数据
title=request.POST.get("title")
models.Department.objects.create(title=title)
return redirect("/depart/list")
修改部门
在urls.py中采用
path("depart/<int:nid>/edit/",views.depart_edit)
的路径方法
def depart_edit(request,nid):
if request.method=="GET":
queryset=models.Department.objects.filter(id=nid)
title=queryset.first().title
return render(request,"depart_edit.html",{"title":title})
title2=request.POST.get("title")
models.Department.objects.filter(id=nid).update(title=title2)
return redirect("/depart/list")
{% 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' %}">
<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>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="/depart/list">部门管理</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><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">注销</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div>
<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 for="exampleInputEmail1">标题
</label>
<input type="text" class="form-control" id="exampleInputEmail1" placeholder="标题" name="title" value="{{ title }}">
</div>
<button type="submit" class="btn btn-primary">保存</button>
</form>
</div>
</div>
</div>
<srcipt src="{% static 'js/jquery-3.6.0.min.js' %}"></srcipt>
<srcipt src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></srcipt>
</body>
</html>
模板继承
创建一个模板网页,把需要重复的部分放进模板layout.html中,使用{% block content %} {% endblock %}编写其他需要改写的地方,其中content是变量名
{% 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' %}">
<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>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="/depart/list">部门管理</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><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">注销</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div>
{% block content %}
{% endblock %}
</div>
<srcipt src="{% static 'js/jquery-3.6.0.min.js' %}"></srcipt>
<srcipt src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></srcipt>
</body>
</html>
例如编辑网页中更改成如下
{% extends "layout.html" %}
{% block content %}
<div>
<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 for="exampleInputEmail1">标题
</label>
<input type="text" class="form-control" id="exampleInputEmail1" placeholder="标题" name="title" value="{{ title }}">
</div>
<button type="submit" class="btn btn-primary">保存</button>
</form>
</div>
</div>
</div>
{% endblock %}
用户管理
在创建user_list.html后,在其中加入后端的数据,需要一些函数的支持,但是模板语法不支持函数()的,所以需要进行省略括号的写法,但是对于一些传参的函数就需要进行改写
{{ obj.create_time|date:“Y-m-d H:i:s” }}是obj.create_time.strftime(‘%Y-%m-%d %H:%M:%S’)的改写
obj.get_gender_display()在前端中的模板语法去掉括号就行了。
总体界面
{% extends "layout.html" %}
{% block content %}
<div>
<div class="container">
<div style = "margin-bottom: 10px">
<a class="btn btn-primary" href="/user/add/" >
{# target="_blank" 在新的页面产生#}
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
新建用户
</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>#</th>
<th>ID</th>
<th>姓名</th>
<th>年龄</th>
<th>工资</th>
<th>入职时间</th>
<th>性别</th>
<th>部门</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for obj in queryset %}
<tr>
<th scope="row">{{ obj.id }}</th>
<td>{{ obj.id }}</td>
<td>{{ obj.name }}</td>
<td>{{ obj.age }}</td>
<td>{{ obj.account }}</td>
<td>{{ obj.create_time|date:"Y-m-d" }}</td>
{# obj.create_time.strftime('%Y-%m-%d %H:%M:%S')#}
<td>{{ obj.get_gender_display }}
{# 模板语法中不能加括号,所以有函数的也不需要加括号#}
</td>
<td>{{ obj.depart.title }}</td>
<td>
<a class = "btn btn-primary btn-xs" href="/user/{{ obj.id }}/edit/">编辑</a>
<a class = "btn btn-danger btn-xs" href="/user/delete/?nid={{ obj.id }}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
后端
def user_list(request):
queryset=models.UserInfo.objects.all()
print(type(queryset))
for obj in queryset:
print(obj.name,obj.age,obj.account,obj.get_gender_display(),obj.password,obj.create_time.strftime('%Y-%m-%d %H:%M:%S'))
return render(request,"user_list.html",{"queryset":queryset})
新建用户
传统方法
{% extends "layout.html" %}
{% block content %}
<div>
<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>姓名
</label>
<input type="text" class="form-control" placeholder="姓名" name="name" >
<label>年龄
</label>
<input type="text" class="form-control" placeholder="年龄" name="age" >
<label>工资
</label>
<input type="text" class="form-control" placeholder="工资" name="account" >
<label>性别
</label>
<input type="text" class="form-control" placeholder="性别" name="gender" >
<label>所属部门ID
</label>
<input type="text" class="form-control" placeholder="所属部门ID" name="depart_id" >
<label>密码
</label>
<input type="text" class="form-control" placeholder="密码" name="password" >
</div>
<button type="submit" class="btn btn-primary">保存</button>
</form>
</div>
</div>
</div>
{% endblock %}
def user_add(request):
if request.method=="GET":
return render(request,"user_add.html")
name=request.POST.get("name")
age = request.POST.get("age")
account = request.POST.get("account")
gender = request.POST.get("gender")
depart_id = request.POST.get("depart_id")
password = request.POST.get("password")
create_time=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
models.UserInfo.objects.create(name=name,age=age,account=account,
gender=gender,password=password,
create_time=create_time,
depart_id=depart_id)
return redirect("/user/list/")
改进
- 用户提交的数据没有校验
- 错误的页面上应该有错误的提示
- 每一个字段都需要重写一遍
- 关联的数据需要手动展示在前端页面
采用Django组件
Form组件
ModelForm组件
ModelForm 组件
class UserModelForm(forms.ModelForm):
class Meta:
model=models.UserInfo
fields=["name","age","account","gender","depart","password"]
def user_modelform_add(request):
"""modelForm版本的添加用户"""
form=UserModelForm()
return render(request,"user_add_modelform.html",{"form":form})
{% extends "layout.html" %}
{% block content %}
<div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">新建面板</h3>
</div>
<div class="panel-body" >
<form method="post">
{% csrf_token %}
{% for field in form %}
{{ field.label }}:{{ field }}<br>
{% endfor %}
<button type="submit" class="btn btn-primary">保存</button>
</form>
</div>
</div>
</div>
{% endblock %}
但是其中部门是下面这样的
利用重写Department类的方法__str__()
class Department(models.Model):
"""部门表"""
id=models.BigAutoField(verbose_name="ID",primary_key=True)#系统默认自己创建
title=models.CharField(verbose_name="标题(备注)",max_length=32)
def __str__(self):
return self.title
{% extends "layout.html" %}
{% block content %}
<div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">新建面板</h3>
</div>
<div class="panel-body" >
<form method="post">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label> {{ field.label }}
</label>
{{ field }}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">保存</button>
</form>
</div>
</div>
</div>
{% endblock %}
加上样式
class UserModelForm(forms.ModelForm):
class Meta:
model=models.UserInfo
fields=["name","age","account","gender","depart","password","create_time"]
# widgets={
# "name":forms.TextInput(attrs={"class":"form-control"}),
# "age": forms.TextInput(attrs={"class": "form-control"}),
# "account": forms.TextInput(attrs={"class": "form-control"}),
# "gender": forms.TextInput(attrs={"class": "form-control"}),
# "depart": forms.TextInput(attrs={"class": "form-control"}),
# }
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
for name,field in self.fields.items():
if name=="create_time":
field.widget.attrs={"class":"form-control","value":time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()),}
else:
field.widget.attrs={"class":"form-control","placeholder":field.label}
后端中进行保存
def user_modelform_add(request):
"""modelForm版本的添加用户"""
if request.method=="GET":
form=UserModelForm()
return render(request,"user_add_modelform.html",{"form":form})
#进行数据校验
form=UserModelForm(data=request.POST)
if form.is_valid():
form.save()#将提交的数据自动保存
print(form.cleaned_data)
return redirect("/user/list/")
else:
print(form.errors)
return render(request,"user_add_modelform.html",{"form":form})
在前端中加入{{ field.errors.0 }}可以显示错误信息
在setting.py中改成LANGUAGE_CODE = "zh-hans"便可以变成中文
编辑
def user_edit(request,nid):
row_object = models.UserInfo.objects.filter(id=nid).first()
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})
{% extends "layout.html" %}
{% block content %}
<div class="container">
<div>
<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>
</div>
{% endblock %}
删除
def user_delete(request):
nid=request.GET.get("nid")
models.UserInfo.objects.filter(id=nid).delete()
return redirect("/user/list/")