?基于前一章Django的安装与使用,这一张继续学习Django的使用方法。
前面已经学了通过ORM对数据库的表进行创建、删除操作,以及对表内新增列和删除列的操作方法。下面接着学通过ORM操作表中的数据。
另外自己试着做一个项目练手。
目录
1 数据库操作
1.1 ORM操作表中数据
1.1.1 衔接与上一章的准备工作
1.1.2、写入数据
1.1.3、删除数据
1.1.4 获取数据
2 项目案例:信息管理系统
2.1 创建项目
2.2 创建app
2.3 设置表类
2.3.1 设置一个部门表
2.3.2 设置一个员工表
2.3.3?在MySQL中生成表
2.4 导入文件
2.5 模板的继承
????????2.5.1 模板 layout.html
????????2.5.2 调用模板
2.6 部门管理
2.6.1 部门url.py
2.6.2 views.py
1 数据库操作
1.1 ORM操作表中数据
1.1.1 衔接与上一章的准备工作
?首先打开models.py文件,写入以下内容(创建两个表单):
class UserInfo(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
age = models.IntegerField(default=20)
# size = models.IntegerField(default=3)
# data = models.CharField(max_length=16, null=True, blank=True)
class DataInfo(models.Model):
title = models.CharField(max_length=16)
然后在终端执行命令:
?创建新的视图函数:
1.1.2、写入数据
在视图函数min中添加数据,需要提前导入models中的表类:
from app01.models import UserInfo, DataInfo
def min(req):
# 添加数据
UserInfo.objects.create(name="吴群其", 密码英文="写入密码", age=16)
DataInfo.objects.create(title="这是一个标题")
return HttpResponse("成功")
运行程序,打开对应页面后,数据添加成功。
1.1.3、删除数据
在min函数中添加以下代码:
# 删除数据
UserInfo.objects.filter(id=4).delete() # 删除id=4的数据
DataInfo.objects.all().delete() # 删除DataInfo表中所有数据
运行程序,刷新页面,UserInfo中id=4的数据和DataInfo中所有数据全部删除。
1.1.4 获取数据
# 获取数据
data_list = UserInfo.objects.all()
print(data_list)
for obj in data_list:
print(obj.id, obj.name, obj.password, obj.age)
?取得的数据data_list是QuerySet类型,可以通过循环遍历得到相关数据。
# 获取id=2的数据,获取的是只包含一个数据的列表
data_list = UserInfo.objects.filter(id=2)
print(data_list)
# 获取id=2列表里面的第一个数据
objdata = UserInfo.objects.filter(id=2).first()
print(objdata)
# 更新数据
# UserInfo.objects.all().update(password=999) # 将所有数据的密码更新为999
# 将id=1的名字更新为 王军发
UserInfo.objects.filter(id=1).update(name="王军发")
2 项目案例:信息管理系统
案例要求:
1.包含部门信息和成员信息
2.能够对部门信息和成员信息进行增删改操作
2.1 创建项目
- 打开pycharm,选择新建项目。
- 新建django项目后,删除Templates目录
- 打开settings.py文件,找到TEMPLATES项,删除DIRS列表里的内容
?一个标准的django项目创建完成
2.2 创建app
- 点击pycharm工具栏里的 运行manage.py项目
- 输入 startapp app01 创建app01
- 注册app(如何注册在上一章有详细介绍,这里不过多赘余,一定要注册,否则app的内容将无法使用)
?2.3 设置表类
设置表类既是构建一个表的内容,比如姓名、年龄、标题等...
同时可以对这些内容进行设置,比如姓名这一项能否为空、最多能有几个字符/数字、工资的小数点保留几位等等
其次还可以将表内的内容与其他表进行级联,比如让员工表的部门与部门表进行关联,当部门表内的部门删除后,对应员工表的内容要发生改变。
注意:以上操作均在 models.py 文件进行。
2.3.1 设置一个部门表
在开发时,要时常进行注释,能直观看懂这一段代码有什么作用
在写表类时,可以用?verbose_name="*****" 进行标注
max_length:设置字符最大长度
创建部门表的具体代码如下:
只需要创建 部门名称 即可,对应id 会自动创建。
class Department(models.Model):
"""部门表"""
title = models.CharField(verbose_name="部门名称", max_length=16)
2.3.2 设置一个员工表
员工表单:账户、密码、姓名、性别、年龄、部门、账户余额、入职时间
账户:整型 (IntegerField)? 最长10个数字
account = models.IntegerField(verbose_name="账户", max_length=10)
密码、姓名:字符串 (CharField)
name = models.CharField(verbose_name='姓名', max_length=6)
password = models.CharField(verbose_name="密码", max_length=16)
性别:小整型(SmallIntegerField),性别只有两个选项(男/女),可以在django做个约束,让性别能够进行选择
gender_choices = (
(1, "男"),
(2, "女"),
)
gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
年龄:整型
age = models.IntegerField(verbose_name="年龄")
部门:多个员工可能在一个部门,是多对一关系(ForeignKey ),需要两个位置参数,一个是关联的模型,另一个是?on_delete ?选项(选择联级删除 CASCADE;这样部门表内删除部门时,对应部门的员工也联级删除);
to 与哪张表关联,to_field? 与表中的哪一列关联;在这里写depart时,会自动生成 depart_id;
depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)
?on_delete ?选项可以设置为 SET_NULL;同时添加null=True, blank=True(允许为空值);这样部门表内删除部门时,员工表内对应员工的部门值将为空
depart = models.ForeignKey(to="Department", to_field="id", null=True, blank=True, on_delete=models.SET_NULL)
账户余额:固定精度的小数(DecimalField)。有两个必须的参数: max_digits(最大位数) 和 decimal_places(小数点位数),默认值为0(刚入职无余额)
account_blc = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
入职时间:日期和时间(DateTimeField)
create_time = models.DateTimeField(verbose_name="入职时间")
员工表类:
class UserInfo(models.Model):
"""员工表"""
account = models.IntegerField(verbose_name="账户", max_length=10)
name = models.CharField(verbose_name='姓名', max_length=6)
password = models.CharField(verbose_name="密码", max_length=16)
gender_choices = (
(1, "男"),
(2, "女"),
)
gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
age = models.IntegerField(verbose_name="年龄")
account_blc = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
depart = models.ForeignKey(verbose_name="部门ID", to="Department", to_field="id", null=True, blank=True, on_delete=models.SET_NULL)
create_time = models.DateTimeField(verbose_name="入职时间")
2.3.3?在MySQL中生成表
create database staffing DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
打卡settings.py 修改DATABASES
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'staffing', # 数据库名字
'USER': 'root', # 账户名
'PASSWORD': '密码', # 密码
'HOST': '127.0.0.1', # MySQL所在的主机
'PORT': 3306, # 端口
}
}
找到工具栏里的运行manage.py,点击后在下面输入
?生成数据表单
?2.4 导入文件
- 将前面HTML学习时用到的static文件(包含里面的css,js等)导入app01:
2.5 模板的继承
在写HTML文件时,每个HTML文件有些固定的编码会重复使用,比如引入css和js等,这里可以用模板进行继承,写一个固定模板,包含所有的重复编码,其他HTML文件直接引用即可。
这里写的固定模板命名为 "layout.html"
2.5.1 模板 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' %}">
<style>
.navbar {
border-radius: 0;
}
</style>
</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><a href="/depart/list">部门管理</a></li>
<li><a href="/user/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 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>
</body>
</html>
2.5.2 调用模板
{#调用模板#}
{% extends 'layout.html' %}
{% block content %}
{#内容#}
{% endblock %}
?通过?extends 调用模板,写入占位符,直接在占位符内写内容即可。
{#调用模板#}
{% extends 'layout.html' %}
{% block content %}
<div>
<div class="container">
<div>
<a href="/depart/add/" target="_blank" class="btn btn-success">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
新建部门
</a>
</div>
<div style="margin-top: 10px">
<div class="bs-example" data-example-id="table-within-panel">
<div class="panel panel-default">
<div class="panel-heading"><span class="glyphicon glyphicon-list" aria-hidden="true"></span>
部门列表
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>部门ID</th>
<th>部门名称</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for dpt in dpt_list %}
<tr>
<th scope="row">{{ dpt.id }}</th>
<td>{{ dpt.title }}</td>
<td>
<a href="/depart/{{ dpt.id }}/edit/" class="btn btn-primary btn-xs">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
编辑
</a>
<a href="/depart/delete/?nid={{ dpt.id }}" class="btn btn-danger btn-xs">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
删除
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{#调用模板#}
{% extends 'layout.html' %}
{% block content %}
<div style="margin-top: 50px" class="container">
<div class="bs-example" data-example-id="table-within-panel">
<div class="panel panel-default">
<div class="panel-heading">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
新建部门
</div>
<form style="margin: 10px 50px" method="post">
{% csrf_token %}
<div class="form-group">
<label>部门名称</label>
<input type="text" class="form-control" name="title" placeholder="部门名称">
</div>
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
添 加
</button>
</form>
</div>
</div>
</div>
{% endblock %}
{#调用模板#}
{% extends 'layout.html' %}
{% block content %}
<div style="margin-top: 50px" class="container">
<div class="bs-example" data-example-id="table-within-panel">
<div class="panel panel-default">
<div class="panel-heading">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
编辑部门
</div>
<form style="margin: 10px 50px" method="post">
{% csrf_token %}
<div class="form-group">
<label>部门名称</label>
<input type="text" class="form-control" name="title" placeholder="部门名称"
value="{{ row.title }}">
</div>
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
修 改
</button>
</form>
</div>
</div>
</div>
{% endblock %}
2.6 部门管理
上面创建完成了部门管理所需要的HTML文件,接下来针对url.py和views.py文件进行处理
2.6.1 部门url.py
打开url.py文件,写入url和对应函数,注意提前导入views模块
from django.urls import path
from app01 import views
urlpatterns = [
# path('admin/', admin.site.urls),
# 部门url
path('depart/list/', views.depart_list),
path('depart/add/', views.depart_add),
# http://127.0.0.1:8000/depart/2/deit/
path('depart/<int:nid>/edit/', views.depart_edit),
path('depart/delete/', views.depart_delete)
]
其中编辑对应的url是有正则表达式的,在depart、deit之间引入正则<int:nid>表示传入nid的整型参数,这个nid对应所要编辑当行数据的id。
2.6.2 views.py
这里放入url对应的函数
from django.shortcuts import render, redirect
from app01 import models
def depart_list(request):
"""部门列表"""
dpt_list = models.Department.objects.all()
return render(request, "depart_list.html", {"dpt_list": dpt_list})
def depart_add(request):
"""添加部门"""
if request.method == "GET":
return render(request, "depart_add.html")
title = request.POST.get("title")
models.Department.objects.create(title=title)
return redirect("/depart/list")
def depart_edit(request, nid):
"""编辑部门"""
if request.method == "GET":
# 根据nid获取对应id数据
row = models.Department.objects.filter(id=nid).first()
# 以传参的形式写入HTML文件
return render(request, "depart_edit.html", {"row": row})
# 获取用户提交的数据标题
title = request.POST.get("title")
# 根据id找到数据库中的数据并进行更新
models.Department.objects.filter(id=nid).update(title=title)
# 重定向回部门列表
return redirect("/depart/list")
def depart_delete(request):
"""删除部门"""
nid = request.GET.get("nid")
models.Department.objects.filter(id=nid).delete()
return redirect("/depart/list")
这样部门管理的所有操作都已经完成。
|