基于Django的管理系统
案例:员工管理系统
创建项目
- 删除pycharm自动增加的
- 删除templates文件
创建app
两种方式创建app,可以在pycharm的终端输入,也可以先pycharm帮助执行一个manage.py
- 终端输入
1
python manage.py startapp app01
- 使用pycharm
- 相当于pycharm帮助执行了一个manage.py
- 直接输入
startapp <文件名>
即可创建
注册app
- 在
settings.py
中注册app
设计表结构
- 新建用户表
- 新建部门表
- 将用户表和部门表进行关联
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28from django.db import models
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)
create_time = models.DateTimeField(verbose_name="入职时间")
# 无约束
# depart_id = models.BigIntegerField(verbose_name="部门ID")
# 部门删除,部门id列置空
# depart_id = models.ForeignKey(to="Department", to_fields="id",null=True, blank=True, on_delete=models.SET_NULL)
# (对部门id进行约束) to 与那张表关联 to_fields 表中哪一列有关联, 级联删除此行
depart_id = models.ForeignKey(to="Department", to_fields="id", on_delete=models.CASCADE)
gender_choices = (
(1, "男"),
(2, "女")
)
gender = models.SmallIntegerField(verbose_name="性别",choices=gender_choices)
在MySQL中生成表
- 工具连接MySQL生成数据库
1
create database djtest;
- 修改
settings.py
数据库配置
1 | DATABASES = { |
基于django命令生成数据库的表
- 命令行执行
1 | python manage.py makemigrations |
manage.py中执行
1 | makemigrations |
- 进入数据库查看
静态文件管理
- 放入文件
列表页面布局
urls.py
```views.py``
depart_list.html
略
- 页面效果
从数据库获取数据
- 如下(以下两个部门为数据库预先输入的)
增删改页面布局设计
- 修改
depart_list.html
- 在
urls.py
中添加path和```views.py``中写入
depart_add.html
略
添加部门
删除部门
- 列表页面删除按钮添加链接
修改部门
模板的继承
- 当我们每个页面都需要保留导航栏的时候,我们对每个HTML都写了一个导航栏,这样有些麻烦,修改时文件过多不易修改,因此我们可以选择模板。
- 模板的定义
- 将我们的插件写在模板中
layout.html
1 |
|
- 继承模板
为了避免一个页面加载不必要的插件,可以多写几个模板,在需要的位置进行填充
1 | {% extends 'layoyt.html' %} |
模板的继承
当我们每个页面都需要保留导航栏的时候,我们对每个HTML都写了一个导航栏,这样白那些麻烦,修改时文件过多不易修改,因此我们可以选择模板。
模板的定义
将我们的插件写在模板中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap3/css/bootstrap.min.css' %}">
</head>
<body>
<h1>标题</h1>
{% block content %}{% endblock %}
<h1>结尾</h1>
<script src="{% static 'js/jquery-3.6.1.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap3/js/bootstrap.min.js' %}"></script>
</body>
</html>继承模板
1
2
3
4
5{% extends 'layoyt.html' %}
{% block content %}
<h1>首页<h1>
{% endblock %}为了避免一个页面加载不必要的插件,可以多写几个模板,在需要的位置进行填充
案例:员工管理系统(部门管理)优化
将导航部分写入模板,列表,添加,编辑页面进行集成
layoyt.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap3/css/bootstrap.min.css' %}">
<style>
.navbar {
border-radius: 0px;
}
</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>
<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="#">用户管理</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>
{% block content %}{% endblock %}
</div>
<script src="{% static 'js/jquery-3.6.1.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap3/js/bootstrap.min.js' %}"></script>
</body>
</html>depart_list.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46{% extends 'layoyt.html' %}
{% block content %}
<div class="container">
<div style="margin-bottom: 10px">
<a class="btn btn-success" href="/depart/add/">
<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>ID</th>
<th>名称</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for obj in querysite %}
<tr>
<th>{{ obj.id }}</th>
<td>{{ obj.title }}</td>
<td>
<a class="btn btn-primary btn-xs" href="/depart/{{ obj.id }}/edit/">编辑</a>
<a class="btn btn-danger btn-xs" href="/depart/delete/?nid={{ obj.id }}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}depart_add.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22{% extends 'layoyt.html' %}
{% 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">
{% csrf_token %}
<div class="form-group">
<label>标题</label>
<input type="text" class="form-control" placeholder="标题" name="title">
</div>
<button type="submit" class="btn btn-primary">提 交</button>
</form>
</div>
</div>
</div>
{% endblock %}depart_edit.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21{% extends 'layoyt.html' %}
{% 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">
{% csrf_token %}
<div class="form-group">
<label>标题</label>
<input type="text" class="form-control" placeholder="标题" name="title" value="{{ row_object.title }}">
</div>
<button type="submit" class="btn btn-primary">提 交</button>
</form>
</div>
</div>
</div>
{% endblock %}
用户管理
- 先手动输入一些数据
1
2
3insert into app01_userinfo(
name,password,age,account,create_time,gender,depart_id)
values("zhang","123",20,10000000,"2022-9-1",1,1);
添加用户
原始方法
问题:
1.用户提交数据没有校验
2.页面输入错误应该有提示
3.错误后,页面每一个数据都需要重新写
4.关联的数据需要手动获取循环展示到页面
- Django组件
- Form组件
可以帮助我们解决前三个问题 - ModelForm组件
- Form组件
初识Form
- view.py
- 自动生成input框
1
2
3
4
5
6
7
8class MyForm(Form):
user = forms.CharFiled(widght=forms.Input)
pwd = forms.CharFiled(widght=forms.Input)
def user_add(request):
"""添加用户(原始方法)"""
if request.method == "GET":
return render(request, 'user_add.html',{"form":form})
- user_add.html
- 循环写
1
2
3
4
5<form method="post">
{% for field in form %}
{{ field }}
{% endfor %}
</form> - 逐一写
1
2
3
4<form method="post">
{{ form.user }}
{{ form.pwd }}
</form>
ModelForm(推荐)
- models.py
1
2
3
4
5
6
7
8
9
10
11
12
13class 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) - view.py
自动生成input框(可以自定义,也可以直接去拿)
1
2
3
4
5
6
7
8
9
10class MyForm(ModelForm):
user = forms.CharFiled(widght=forms.Input)
class Mete:
model = UserInfo
field = ["name","user","password","age"]
def user_add(request):
"""添加用户(原始方法)"""
if request.method == "GET":
return render(request, 'user_add.html',{"form":form})设置settings.py 将默认文字为中文
员工管理系统(用户管理)
user_model_form_add.html
1 | {% extends 'layoyt.html' %} |
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15def user_model_form_add(request):
"""基于modelform的添加用户"""
if request.method == "GET":
form = UserModelForm
return render(request,'user_model_form_add.html', {"form": form})
# 用户POST提交数据,数据校验
form = UserModelForm(data=request.POST)
if form.is_valid():
# 数据合法,保存到数据库
# models.UserInfo.objects.create()
form.save()
return redirect("/user/list/")
else:
return render(request,'user_model_form_add.html', {"form": form})补充编辑删除以后的代码
- 编辑用户
- 点击编辑,跳转到编辑页面(将编辑行的id携带过去)
- 错误校验
- 数据库更新
- 删除用户
views.py
1 | def user_edit(request, nid): |
user_model_form_edit.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29{% extends 'layoyt.html' %}
{% 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>
{% 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>
{% endblock %}其它修改
号码管理
表结构
- 设计表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class PrettyNum(models.Model):
"""靓号表"""
mobile = models.CharField(verbose_name="手机号", max_length=11)
price = models.IntegerField(verbose_name="价格", default=0)
level_choices = (
(1, "1级"),
(2, "2级"),
(3, "3级"),
(4, "4级"),
)
level = models.SmallIntegerField(verbose_name="级别", choices=level_choices, default=1)
status_choices = (
(1, "已占用"),
(2, "未使用"),
)
status = models.SmallIntegerField(verbose_name="状态", choices=status_choices, default=2) - 命令创建表
号码列表
- URL
- 函数
- 获取所有的靓号
- 结合HTML+render将靓号罗列出来
1 | def pretty_list(request): |
pretty_list.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62{% extends 'layoyt.html' %}
{% block content %}
<div class="container">
<div style="margin-bottom: 10px" class="clearfix">
<a class="btn btn-success" href="/pretty/add/">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
新建靓号
</a>
<div style="float: right; width: 300px;">
<form method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search for..."
value="{{ search_data }}">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
</button>
</span>
</div><!-- /input-group -->
</form>
</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>
</tr>
</thead>
<tbody>
{% for obj in queryset %}
<tr>
<th>{{ obj.id }}</th>
<td>{{ obj.mobile }}</td>
<td>{{ obj.price }}</td>
<td>{{ obj.get_level_display }}</td>
<td>{{ obj.get_status_display }}</td>
<td>
<a class="btn btn-primary btn-xs" href="/pretty/{{ obj.id }}/edit/">编辑</a>
<a class="btn btn-danger btn-xs" href="/pretty/{{ obj.id }}/delete/">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
新建号码
- 列表页面点击跳转:/pretty/add/
- URL
- 函数
- ModelForm的类
- 函数
- 实例化类的对象
- 通过render将对象传入HTML中
- 模板的循环展示所有的字段
- 点击提交
- 数据校验
- 保存到数据库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39class PrettyModelForm(forms.ModelForm):
# 验证:方式一
# 通过正则表达式规范校验手机号码
mobile = forms.CharField(
label="手机号",
validators=[RegexValidator(r'^1\d{8}', "号码格式错误")]
)
class Meta:
model = models.PrettyNum
# fields = "__all__"
fields = ["mobile", "price", "level", "status"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for name, field in self.fields.items():
field.widget.attrs = {"class": "form-control"}
# 验证:方式二
def clean_mobile(self):
txt_mobile = self.cleaned_data["mobile"]
exits = models.PrettyNum.objects.filter(mobile=txt_mobile).exists()
if exits:
raise ValidationError("手机号已存在")
return txt_mobile
def pretty_add(request):
"""添加靓号"""
if request.method == "GET":
form = PrettyModelForm()
return render(request, 'pretty_add.html', {"form": form})
form = PrettyModelForm(data=request.POST)
if form.is_valid():
form.save()
return redirect("/pretty/list/")
else:
return render(request, 'pretty_add.html', {"form": form})
pretty_add.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29{% extends 'layoyt.html' %}
{% 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>
{% 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>
{% endblock %}编辑号码
- 列表页面点击跳转:/pretty/edit/
- URL
- 函数
- 根据id获取当前编辑的对象
- ModelForm配合,默认显示数据
- 提交修改
不允许靓号重复
- 添加(正则表达式)
- 编辑(正则表达式)
1 | class PrettyEditModelForm(forms.ModelForm): |
pretty_edit.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29{% extends 'layoyt.html' %}
{% 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>
{% 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>
{% endblock %}删除号码
1
2
3def pretty_delete(request, nid):
models.PrettyNum.objects.filter(id=nid).delete()
return redirect('/pretty/list')
分页和分页组件
分页(一般写法)
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85def pretty_list(request):
"""靓号列表"""
data_dict = {}
search_data = request.GET.get('q', "")
if search_data:
data_dict['mobile__contains'] = search_data
page = int(request.GET.get('page', 1))
page_size = 10
start = (page - 1) * page_size
end = page * page_size
# 数据总条数
total_count = models.PrettyNum.objects.filter(**data_dict).order_by("-level").count()
queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-level")[start:end]
# 总页码
total_page_count, div = divmod(total_count, page_size)
if div:
total_page_count += 1
# 计算出当前页得到前五页和后五页
plus = 5
if total_page_count <= 2 * plus + 1:
start_page = 1
end_page = total_page_count + 1
else:
# 数据库数据比较多 > 11 页
if page <= plus:
start_page = 1
end_page = 2 * plus + 1
else:
if (page + plus) > total_page_count:
start_page = total_page_count - 2 * plus
end_page = total_page_count
else:
start_page = page - plus
end_page = page + plus + 1
# 页码
page_str_list = []
page_str_list.append('<li><a href="?page={}">首页</a></li>'.format(1))
# 上一页
if page > 1:
prev = '<li><a href="?page={}">上一页</a></li>'.format(page - 1)
else:
prev = '<li><a href="?page={}">上一页</a></li>'.format(1)
page_str_list.append(prev)
for i in range(start_page, end_page):
if i == page:
ele = '<li class="active"><a href="?page={}">{}</a></li>'.format(i, i)
else:
ele = '<li><a href="?page={}">{}</a></li>'.format(i, i)
page_str_list.append(ele)
# 下一页
if page < total_page_count:
prev = '<li><a href="?page={}">下一页</a></li>'.format(page + 1)
else:
prev = '<li><a href="?page={}">下一页</a></li>'.format(total_page_count)
page_str_list.append(prev)
# 尾页
page_str_list.append('<li><a href="?page={}">尾页</a></li>'.format(total_page_count))
search_string = """
<li>
<form style="float: left; margin-left: -1px" method="get">
<div class="input-group" style="width: 200px" >
<input type="text" name="page" class="form-control" placeholder="页数">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">跳转</button>
</span>
</div>
</form>
</li>
"""
page_str_list.append(search_string)
page_string = mark_safe("".join(page_str_list))
return render(request, 'pretty_list.html',
{"queryset": queryset, "search_data": search_data, "page_string": page_string}, )pretty_list
- 效果展示
分页组件的封装
- 新建文件
用pagination
公共组件
pagination
1 | """ |
bug
- 在搜索下分页查询不保留搜索条件
在分页的时候,保留搜索条件
pagination.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145"""
自定义的分页组件,以后如果想要使用分页组件
在视图函数中
def pretty_list(request):
# 根据自己的情况去筛选自己的数据
queryset = models.PrettyNum.objects.all()
# 实例化分页对象
page_object = Pagination(request, queryset)
context = {
"search_data": search_data,
"queryset": page_object.page_queryset, # 分完页的数据
"page_string": page_object.html() # 页码
}
return render(request, 'pretty_list.html', context)
在HTML页面中
{% for obj in queryset %}
{{ obj.xx }}
{% endfor %}
<ul class="pagination">
{{ page_string }}
</ul>
"""
from django.utils.safestring import mark_safe
import copy
class Pagination(object):
def __init__(self, request, queryset, page_size=10, page_param="page", plus=5):
"""
:param request: 请求的对象
:param queryset: 查询的符合条件的数据(根据这个数据进行处理)
:param page_size: 每页显示多少条数据
:param page_param: 在URL中传递的参数
:param plus: 显示当前页的前或后几页
"""
query_dict = copy.deepcopy(request.GET)
query_dict._mutable = True
self.query_dict = query_dict
self.page_param = page_param
page = request.GET.get(page_param, "1")
if page.isdecimal():
page = int(page)
else:
page = 1
self.page = page
self.page_size = page_size
self.start = (page - 1) * page_size
self.end = page * page_size
self.page_queryset = queryset[self.start:self.end]
total_count = queryset.count()
total_page_count, div = divmod(total_count, page_size)
if div:
total_page_count += 1
self.total_page_count = total_page_count
self.plus = plus
def html(self):
# 计算出当前页得到前五页和后五页
if self.total_page_count <= 2 * self.plus + 1:
start_page = 1
end_page = self.total_page_count + 1
else:
# 数据库数据比较多 > 11 页
if self.page <= self.plus:
start_page = 1
end_page = 2 * self.plus + 1
else:
if (self.page + self.plus) > self.total_page_count:
start_page = self.total_page_count - 2 * self.plus
end_page = self.total_page_count
else:
start_page = self.page - self.plus
end_page = self.page + self.plus + 1
# 页码
page_str_list = []
self.query_dict.setlist(self.page_param,[1])
page_str_list.append('<li><a href="?{}">首页</a></li>'.format(self.query_dict.urlencode()))
# 上一页
if self.page > 1:
self.query_dict.setlist(self.page_param, [self.page - 1])
prev = '<li><a href="?{}">上一页</a></li>'.format(self.query_dict.urlencode())
else:
self.query_dict.setlist(self.page_param, [1])
prev = '<li><a href="?{}">上一页</a></li>'.format(self.query_dict.urlencode())
page_str_list.append(prev)
for i in range(start_page, end_page):
self.query_dict.setlist(self.page_param, [i])
if i == self.page:
ele = '<li class="active"><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
else:
ele = '<li><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
page_str_list.append(ele)
# 下一页
if self.page < self.total_page_count:
self.query_dict.setlist(self.page_param, [self.page + 1])
self.query_dict.urlencode()
prev = '<li><a href="?{}">下一页</a></li>'.format(self.query_dict.urlencode())
else:
self.query_dict.setlist(self.page_param, [self.total_page_count])
prev = '<li><a href="?{}">下一页</a></li>'.format(self.query_dict.urlencode())
page_str_list.append(prev)
# 尾页
self.query_dict.setlist(self.page_param, [self.total_page_count])
page_str_list.append('<li><a href="?{}">尾页</a></li>'.format(self.query_dict.urlencode()))
search_string = """
<li>
<form style="float: left; margin-left: -1px" method="get">
<div class="input-group" style="width: 200px" >
<input type="text" name="page" class="form-control" placeholder="页数">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">跳转</button>
</span>
</div>
</form>
</li>
"""
page_str_list.append(search_string)
page_string = mark_safe("".join(page_str_list))
return page_string
使用
- 放在任意py文件中,在用的文件中进行导入
- 具体操作说明
管理员操作
文件目录结构
urls.py
admin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149from django.shortcuts import render, redirect
from app01 import models
from app01.utils.pagiantion import Pagination
def admin_list(request):
"""管理员列表"""
# 搜索
data_dict = {}
search_data = request.GET.get('q', "")
if search_data:
data_dict['username__contains'] = search_data
queryset = models.Admin.objects.filter(**data_dict)
# 分页
page_object = Pagination(request, queryset)
context = {
"queryset": page_object.page_queryset,
"page_string": page_object.html(),
"search_data": search_data,
}
return render(request, "admin_list.html", context)
from django import forms
from django.core.exceptions import ValidationError
from app01.utils.bootstrap import BootStrapModelForm
from app01.utils.encrtpt import md5
class AdminModelForm(BootStrapModelForm):
confirm_password = forms.CharField(
label="确认密码",
widget=forms.PasswordInput(render_value=True)
)
class Meta:
model = models.Admin
fields = ['username', 'password', "confirm_password"]
widgets = {
"password": forms.PasswordInput(render_value=True)
}
def clean_password(self):
pwd = self.cleaned_data.get("password")
return md5(pwd)
def clean_confirm_password(self):
pwd = self.cleaned_data.get("password")
confirm = md5(self.cleaned_data.get("confirm_password"))
if confirm != pwd:
raise ValidationError("密码不一致")
return confirm
class AdminEditModelForm(BootStrapModelForm):
class Meta:
model = models.Admin
fields = ['username']
class AdminResetModelForm(BootStrapModelForm):
confirm_password = forms.CharField(
label="确认密码",
widget=forms.PasswordInput(render_value=True)
)
class Meta:
model = models.Admin
fields = ['password' , 'confirm_password']
def clean_password(self):
pwd = self.cleaned_data.get("password")
md5_pwd = md5(pwd)
# 去数据库校验当前密码和数据库是否一致
exists = models.Admin.objects.filter(id=self.instance.pk, password=md5_pwd).exists()
if exists:
raise ValidationError("密码不能与以前的相同")
return md5(pwd)
def clean_confirm_password(self):
pwd = self.cleaned_data.get("password")
confirm = md5(self.cleaned_data.get("confirm_password"))
if confirm != pwd:
raise ValidationError("密码不一致")
return confirm
def admin_add(request):
"""添加管理员"""
title = "新建管理员"
if request.method == "GET":
form = AdminModelForm()
return render(request, 'change.html', {"form": form, "title": title})
form = AdminModelForm(data=request.POST)
if form.is_valid():
form.save()
return redirect('/admin/list')
return render(request, 'change.html', {"form": form, "title": title})
def admin_edit(request, nid):
"""编辑管理员"""
row_object = models.Admin.objects.filter(id=nid).first()
if not row_object:
# return render(request, 'error.html', {"msg": "数据不存在"})
return redirect('/admin/list/')
title = "编辑管理员"
if request.method == "GET":
form = AdminEditModelForm(instance=row_object)
return render(request, 'change.html', {"form": form, "title": title})
form = AdminEditModelForm(data=request.POST, instance=row_object)
if form.is_valid():
form.save()
return redirect('/admin/list/')
return render(request, 'change.html', {"form": form, "title": title})
def admin_delete(request, nid):
"""删除管理员"""
models.Admin.objects.filter(id=nid).delete()
return redirect('/admin/list/')
def admin_reset(request, nid):
"""重置密码"""
row_object = models.Admin.objects.filter(id=nid).first()
if not row_object:
return redirect('/admin/list/')
title = "重置密码-{}".format(row_object.username)
if request.method == "GET":
form = AdminResetModelForm()
return render(request, 'change.html', {"form": form ,"title": title})
form = AdminResetModelForm(data=request.POST, instance=row_object)
if form.is_valid():
form.save()
return redirect('/admin/list/')
return render(request, 'change.html', {"form": form, "title": title})admin_list.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70{% extends 'layoyt.html' %}
{% block content %}
<div class="container">
<div style="margin-bottom: 10px" class="clearfix">
<a class="btn btn-success" href="/admin/add/">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
新建管理员
</a>
<div style="float: right; width: 300px;">
<form method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="关键字"
value="{{ search_data }}">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
</button>
</span>
</div><!-- /input-group -->
</form>
</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>
</tr>
</thead>
<tbody>
{% for obj in queryset %}
<tr>
<th>{{ obj.id }}</th>
<td>{{ obj.username}}</td>
<td>********</td>
<td>
<a href="/admin/{{ obj.id }}/reset/">重置密码</a>
</td>
<td>
<a class="btn btn-primary btn-xs" href="/admin/{{ obj.id }}/edit/">编辑</a>
<a class="btn btn-danger btn-xs" href="/admin/{{ obj.id }}/delete/">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div>
<ul class="pagination">
{{ page_string }}
</ul>
</div>
</div>
</div>
{% endblock %}change.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29{% extends 'layoyt.html' %}
{% block content %}
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{ 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>
{% endblock %}error.html
1
2
3
4
5
6
7
8{% extends 'layoyt.html' %}
{% block content %}
<div class="container">
<div class="alert alert-danger" role="alert">{{ msg }}</div>
</div>
{% endblock %}
用户登录
1 | http://127.0.0.1:8000/user/list/ |
无状态&短链接
一次请求一次响应(每次默认为新请求,不携带以前的状态)cookie和session
cookie:保存在浏览器上的键值对,发送请求时,自动携带
session:服务端存储我们信息的地方
发起请求后,网站可以在浏览器上写一个键值对,会给你一个响应体(页面),还有一个响应头(cookie),会生成一个专属的凭证。
登录界面
login.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap3/css/bootstrap.min.css' %}">
<style>
.acount {
width: 400px;
border: 1px solid #ddd;
box-shadow: 5px 5px 5px #aaa;
margin-left: auto;
margin-right: auto;
margin-top: 100px;
padding: 20px 30px;
}
.acount h1 {
text-align: center;
}
</style>
</head>
<body>
<div class="acount">
<h2>用户登录</h2>
<form method="post" novalidate>
{% csrf_token %}
<div class="form-group" >
<label>用户名</label>
{{ form.username }}
<span style="color: red">{{ form.username.errors.0 }}</span>
</div>
<div class="form-group">
<label>密码</label>
{{ form.password }}
<span style="color: red">{{ form.username.errors.0 }}</span>
</div>
<button type="submit" class="btn btn-primary">登录</button>
</form>
</div>
</body>
</html>account.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43from django.shortcuts import render, redirect, HttpResponse
from django import forms
from app01 import models
from app01.utils.bootstrap import BootStrapForm
from app01.utils.encrtpt import md5
class LoginForm(BootStrapForm):
username = forms.CharField(
label="用户名",
widget=forms.TextInput,
required=True
)
password = forms.CharField(
label="密码",
widget=forms.TextInput,
required=True
)
def clean_password(self):
pwd = self.cleaned_data.get("password")
return md5(pwd)
def login(request):
"""登录"""
if request.method == "GET":
form = LoginForm()
return render(request, 'login.html', {'form': form})
form = LoginForm(data=request.POST)
if form.is_valid():
# 验证成功后,获取到的用户名和密码,去数据校验(前提字典的键值和数据库一致)
admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
if not admin_object:
form.add_error("username", "用户名或密码错误")
return render(request, 'login.html', {'form': form})
# 验证通过后
# 网站生成随机字符串,写到用户浏览器的cookie中:再写入到session中
request.session["info"] = {'id': admin_object.id, 'name': admin_object.username}
return redirect("/admin/list")
return render(request, 'login.html', {'form': form})用户验证
登录成功后:
cookie:随机字符串
session:用户信息
在其他需要登录才能访问的页面中都需要加入:1
2
3
4
5
6def admin_list(request):
# 检查用户是否已经登录,已登录,继续,未登录,跳转至登录界面
# 用户发来的请求,获取cookie随机字符串,拿着字符串看看session有没有
info = request.session.get("info")
if not info:
return redirect('/login/')需要在18个页面都加入,过于繁琐,此时可使用django的中间件
中间件
请求进入网站会通过中间件,出去也会通过中间件(中间件其实就相当一个类)
当中间件阻拦请求后,就会从中间件返回,用户就无法访问到视图函数
中间件的使用
- 定义中间件
- 写一个类
- 使用中间件
- settings.py中注册中间件
在中间件中没有返回值继续走,如果有返回值则继续向后走
注销
Ajax请求
浏览器向网站发送请求时候:URL和表单的形式提交
- GET
- POST
特点:页面会刷新。
除此之外,也可以基于Ajax向后台发请求(页面不会做刷新) - 依赖jQuery
- 编写Ajax代码
get请求
1 | $.ajax( |
1 | from django.shortcuts import render, HttpResponse |
post请求
1 | $.ajax( |
对于post请求需要携带session,这个过程过于繁琐,可以采用免除csrf_token认证
1 | from django.shortcuts import render, HttpResponse |
关于绑定事件
1 | {% extends 'layoyt.html' %} |
ajax请求的返回值
返回的是json格式
案例:表单
task_list.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59{% extends 'layoyt.html' %}
{% block content %}
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">表单</div>
<div class="panel-body">
<form id="formAdd">
<div class="clearfix">
{% for field in form %}
<div class="form-group col-xs-6" style="position: relative;margin-bottom: 20px">
<label>{{ field.label }}</label>
{{ field }}
<span class="error-msg" style="color: red;position: absolute"></span>
</div>
{% endfor %}
<div class="col-xs-12">
<button id="btnAdd" type="button" class="btn btn-primary">提 交</button>
</div>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script type="text/javascript">
$(function () {
//页面加载完成之后代码自动执行
bindBtnAddEvent();
})
function bindBtnAddEvent() {
$("#btnAdd").click(function () {
$(".error-msg").empty();
$.ajax({
url: '/task/add/',
type: "post",
data: $("#formAdd").serialize(),
dataType: "JSON",
success: function (res) {
if(res.status){
alert("添加成功")
}else{
$.each(res.error,function (name,data){
$("#id_" + name).next().text(data[0]);
})
}
}
})
})
}
</script>
{% endblock %}task.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38import json
from django import forms
from django.shortcuts import render, HttpResponse
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from app01 import models
from app01.utils.bootstrap import BootStrapModelForm
class TaskModeForm(BootStrapModelForm):
class Meta:
model = models.Task
fields = "__all__"
widgets = {
# "detail": forms.Textarea
"detail": forms.TextInput
}
def task_list(request):
"""任务列表"""
form = TaskModeForm
return render(request, 'task_list.html' , {"form":form})
def task_add(request):
print(request.POST)
# 1.用户发送过来的数据进行校验()
form = TaskModeForm(data=request.POST)
if form.is_valid():
form.save()
data_dict = {"status": True}
return HttpResponse(json.dumps(data_dict))
data_dict = {"status": False, 'error': form.errors}
return HttpResponse(json.dumps(data_dict, ensure_ascii=False))
基于Ajax的订单管理
创建表结构
1 | class Order(models.Model): |
前端页面
order_list.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259{% extends 'layoyt.html' %}
{% block content %}
<div class="container">
<div>
<input id="btnAdd" type="button" value="新建订单" class="btn btn-primary">
</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>
</tr>
</thead>
<tbody>
{% for obj in queryset %}
<tr>
<th>{{ obj.id }}</th>
<td>{{ obj.oid }}</td>
<td>{{ obj.title }}</td>
<td>{{ obj.price }}</td>
<td>{{ obj.get_status_display }}</td>
<td>{{ obj.admin.username }}</td>
<td>
<input uid="{{ obj.id }}" type="button" class="btn btn-primary btn-xs btn-edit" value="编辑">
<input uid="{{ obj.id }}" class="btn btn-danger btn-xs btn-delete" type="button" value="删除">
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<ul class="pagination">
{{ page_string }}
</ul>
<!-- 新建/编辑 订单Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">新建</h4>
</div>
<div class="modal-body">
<form id="formAdd">
<div class="clearfix">
{% for field in form %}
<div class="form-group col-xs-6" style="position: relative;margin-bottom: 20px">
<label>{{ field.label }}</label>
{{ field }}
<span class="error-msg" style="color: red;position: absolute"></span>
</div>
{% endfor %}
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取 消</button>
<button id="btnSave" type="button" class="btn btn-primary">保 存</button>
</div>
</div>
</div>
</div>
<!-- 删除Modal -->
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="alert alert-danger alert-dismissible fade in" role="alert">
<h4>是否确定删除</h4>
<p>删除后所有关联的相关数据都将会被删除。</p>
<p style="text-align: right">
<button id="btnConfirmDelete" type="button" class="btn btn-danger">确定</button>
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
</p>
</div>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script type="text/javascript">
var DELETE_ID;
var EDIT_ID;
$(function () {
bindBtnAddEvent();
bindBtnSaveEvent();
bindBtnDeleteEvent();
bindBtnConfirmDelete();
bindBtnEditDelete();
})
function bindBtnAddEvent() {
$("#btnAdd").click(function () {
// 将当前的编辑置空
EDIT_ID = undefined;
$("#formAdd")[0].reset();
$('#myModalLabel').text("新建");
//点击新建按钮,显示订单
$('#myModal').modal('show');
})
}
function bindBtnSaveEvent() {
$("#btnSave").click(function () {
// 清除错误信息
$(".error-msg").empty();
if(EDIT_ID){
// 编辑
doEdit();
}else{
// 添加
doAdd();
}
})
}
function doEdit(){
// 向后台发送信息(添加的ajax请求)
$.ajax({
url: "/order/edit/" + "?uid=" + EDIT_ID, //编辑的id
type: "post",
data: $("#formAdd").serialize(),
dataType: "JSON",
success: function (res) {
if (res.status) {
// 清空表单
$("#formAdd")[0].reset();
// 关闭对话框
$('#myModal').modal('hide');
location.reload();
} else {
if (res.tips) {
alert(res.tips);
} else {
$.each(res.error, function (name, errorList) {
$("#id_" + name).next().text(errorList[0]);
})
}
}
}
})
}
function doAdd(){
// 向后台发送信息(添加的ajax请求)
$.ajax({
url: '/order/add/',
type: "post",
data: $("#formAdd").serialize(),
dataType: "JSON",
success: function (res) {
if (res.status) {
alert("创建成功");
$("#formAdd")[0].reset();
$('#myModal').modal('hide');
location.reload();
} else {
$.each(res.error, function (name, errorList) {
$("#id_" + name).next().text(errorList[0]);
})
}
}
})
}
function bindBtnDeleteEvent() {
$(".btn-delete").click(function () {
// alert("确认删除");
$('#deleteModal').modal('show');
// 获取uid赋值给全局变量
DELETE_ID = $(this).attr("uid");
});
}
function bindBtnConfirmDelete() {
$("#btnConfirmDelete").click(function () {
// 点击确定删除,将DELETEID发送到后台
$.ajax({
url: "/order/delete/",
type: "GET",
data:{
uid: DELETE_ID
},
dataType: "JSON",
success: function (res){
if (res.status) {
alert("删除成功");
location.reload();
} else {
alert(res.error);
}
}
})
})
}
function bindBtnEditDelete(){
$(".btn-edit").click(function (){
$("#formAdd")[0].reset();
var uid = $(this).attr("uid");
EDIT_ID = uid;
// 发送ajax请求去后台获取数据
$.ajax({
url: "/order/detail/",
type: "get",
data: {
uid: uid
},
success: function (res) {
if (res.status) {
// 将数据赋值
$.each(res.data, function (name,value){
$("#id_" + name).val(value);
})
// 修改对话框标题
$('#myModalLabel').text("编辑");
//点击编辑,显示对话框
$('#myModal').modal('show');
} else {
alert(res.error);
}
}
})
// 在对话框中默认看到
})
}
</script>
{% endblock %}后台管理
order.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106import random
from datetime import datetime
from django.shortcuts import render
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from app01.utils.bootstrap import BootStrapModelForm
from app01 import models
from app01.utils.pagiantion import Pagination
class OrderModelForm(BootStrapModelForm):
class Meta:
model = models.Order
# fields = "__all__"
exclude = ["oid", "admin"]
def order_list(request):
"""订单列表"""
queryset = models.Order.objects.all().order_by('-id')
page_object = Pagination(request, queryset)
form = OrderModelForm
context = {
"form": form,
"queryset": page_object.page_queryset,
"page_string": page_object.html()
}
return render(request, 'order_list.html', context)
def order_add(request):
"""新建订单(ajax)"""
form = OrderModelForm(data=request.POST)
if form.is_valid():
# 生成订单号
form.instance.oid = datetime.now().strftime("%Y%m%d%H%M%S") + str(random.randint(1000, 9999))
# 固定设置管理员(当前登录系统的人的id)
form.instance.admin_id = request.session["info"]["id"]
# 保存到数据库
form.save()
return JsonResponse({"status": True})
return JsonResponse({"status": False, "error": form.errors})
def order_delete(requeset):
"""删除订单"""
uid = requeset.GET.get("uid")
exists = models.Order.objects.filter(id=uid).exists()
if not exists:
return JsonResponse({"status": False, 'error':"数据不存在"})
models.Order.objects.filter(id=uid).delete()
return JsonResponse({"status": True})
def order_detail(requeset):
"""根据id获取订单详情"""
# 方式一
"""
uid = requeset.GET.get("uid")
row_object = models.Order.objects.filter(id=uid).first()
if not row_object:
return JsonResponse({"status": False, 'error': "数据不存在"})
# 从数据库中获取到一个对象 row_object
result = {
"status": True,
"data": {
"title": row_object.title,
"price": row_object.price,
"status": row_object.status,
}
}0
return JsonResponse({"status": True, "data": result})
"""
# 方式二
uid = requeset.GET.get("uid")
row_dict = models.Order.objects.filter(id=uid).values("title","price","status").first()
if not row_dict:
return JsonResponse({"status": False, 'error': "数据不存在"})
# 从数据库中获取到一个对象 row_object
result = {
"status": True,
"data": row_dict,
}
return JsonResponse(result)
def order_edit(request):
"""编辑订单"""
uid = request.GET.get("uid")
row_object = models.Order.objects.filter(id=uid).first()
if not row_object:
return JsonResponse({"status": False, 'tips': "数据不存在"})
form = OrderModelForm(data=request.POST, instance=row_object)
if form.is_valid():
form.save()
return JsonResponse({"status": True})
return JsonResponse({"status": False, 'error': form.errors})路径