项目实战

  • 项目开发流程
  • 项目准备工作
  • 项目部门管理
    • UI设计
    • depart_list
    • 模板继承
    • depart_add
    • depart_delete
    • depart_edit
  • 项目用户管理
    • user_list
    • user_add
    • Form和ModelForm
      • Form
      • ModelForm
    • user_add(ModelForm)
    • user_edit
    • user_delete

号外号外,基于Pycharm的Django学习,项目实战来啦!

项目开发流程

实战之前,我们先来结合前面学习的知识,捋一捋整个项目开发的流程:

  1. 新建项目
  2. 创建app并注册
  3. 设计表结构
  4. 在MYSQL生成表
  5. 静态文件管理
  6. 代码编写
  7. 测试

项目准备工作

上述1-5,其实我们在之前就已经接触过了,所以在这个项目实战中,就当作是准备工作,大家先提前完成,有不懂的也可以看我之前写的博客。

第一步:新建项目


第二步:创建app并注册


第三步:设计表结构

from django.db import models# Create your models here.class Department(models.Model):"""部门表"""# verbose_name注解 相当于给我们程序员自己看代码时的字段含义提示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="年龄")# max_digits表示最大位数 decimal_places表示小数位数 default表示默认值account = models.DecimalField(verbose_name="账户", max_digits=10, decimal_places=2, default=0)create_time = models.DateTimeField(verbose_name="入职时间")# 存入外键 表示员工所属部门ID 节省存储字节数 需要加入约束 即只能是部门表中已经存在的id 并且需要设置当部门表被删除 其为级联删除或者可以置空# 存入名称 表示员工所属部门名称 主要用于优化检索速度# to表示和哪张表连接  to_field表示和哪个字段连接 on_delete表示部门表删除时员工表做出的操作depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)# Django约束 由于性别只有男和女 所以可以通过choices选择哪一些gender_choices = ((1, "男"),(2, "女"))gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)

第四步:在MYSQL生成表

DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql',# 数据库名字'NAME':'写自己的名字',# 用户名'USER': 'root',# 密码'PASSWORD': '写自己的密码',# 主机'HOST': 'localhost',# 端口'PORT': '3306',}
}
python manage.py makemigrations
python manage.py migrate


第五步:静态文件管理


项目部门管理

UI设计

先看一下页面大致UI设计:

depart_list

于是开始编写页面:


页面整体布局采用的是bootstrap框架,上面的是一个导航条,下面的是一个面板加表格的结构,先使用的静态数据进行测试页面。

大部分需要实现跳转的,哪怕长得再像按钮,其实都是一个a标签,然后设置class为btn属性。

{% load static %}<!doctype html>
<html lang="zh-CN">
<head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Title</title><!--rel="stylesheet"不能缺少 否则显示不出来样式 rel属性就是指明你链进来的对象是个什么东西 stylesheet表示是样式表--><link rel="stylesheet" href="{% static '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></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="true"><spanclass="glyphicon glyphicon-user"></span>个人信息<span class="caret"></span></a><ul class="dropdown-menu"><li><a href="#"><spanclass="glyphicon glyphicon-tree-conifer"></span>昵称:王晓曼</a></li><li role="separator" class="divider"></li><li><a href="#"><spanclass="glyphicon glyphicon-music"></span>个性签名:关关难过关关过,前路漫漫亦灿灿。</a></li></ul></li></ul></div></div>
</nav>
<div><div class="container"><div style="margin-bottom:20px"><!--span后一个换行使得字体图标和文字有一点空隙--><a class="btn btn-primary" href="#"><span class="glyphicon glyphicon-plus-sign"></span>新建部门</a></div><!--面板+表格--><div><div class="panel panel-default"><div class="panel-heading"><span class="glyphicon glyphicon-th-list"></span>部门列表</div><!--可以直接在浏览器中选中元素 copy element--><table class="table table-bordered"><thead><tr><th>ID</th><th>名称</th><th>操作</th></tr></thead><tbody><tr><th scope="row">1</th><td>销售部</td><td><a class="btn btn-success btn-xs">编辑</a><a class="btn btn-danger btn-xs">删除</a></td></tr><tr><th scope="row">2</th><td>技术部</td><td><a class="btn btn-success btn-xs">编辑</a><a class="btn btn-danger btn-xs">删除</a></td></tr><tr><th scope="row">3</th><td>广告部</td><td><a class="btn btn-success btn-xs">编辑</a><a class="btn btn-danger btn-xs">删除</a></td></tr></tbody></table></div></div></div>
</div>
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
</body>
</html>


下面将静态数据换成从数据库进行获取的数据。

{% load static %}<!doctype html>
<html lang="zh-CN">
<head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Title</title><!--rel="stylesheet"不能缺少 否则显示不出来样式 rel属性就是指明你链进来的对象是个什么东西 stylesheet表示是样式表--><link rel="stylesheet" href="{% static '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></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="true"><spanclass="glyphicon glyphicon-user"></span>个人信息<span class="caret"></span></a><ul class="dropdown-menu"><li><a href="#"><spanclass="glyphicon glyphicon-tree-conifer"></span>昵称:王晓曼</a></li><li role="separator" class="divider"></li><li><a href="#"><spanclass="glyphicon glyphicon-music"></span>个性签名:关关难过关关过,前路漫漫亦灿灿。</a></li></ul></li></ul></div></div>
</nav>
<div><div class="container"><div style="margin-bottom:20px"><!--span后一个换行使得字体图标和文字有一点空隙--><a class="btn btn-primary" href="#"><span class="glyphicon glyphicon-plus-sign"></span>新建部门</a></div><!--面板+表格--><div><div class="panel panel-default"><div class="panel-heading"><span class="glyphicon glyphicon-th-list"></span>部门列表</div><!--可以直接在浏览器中选中元素 copy element--><table class="table table-bordered"><thead><tr><th>ID</th><th>名称</th><th>操作</th></tr></thead><tbody>{% for data in data_list %}<tr><th scope="row">{{data.id}}</th><td>{{data.title}}</td><td><a class="btn btn-success btn-xs">编辑</a><a class="btn btn-danger btn-xs">删除</a></td></tr>{% endfor %}</tbody></table></div></div></div>
</div>
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
</body>
</html>

效果和上述一样,只不过这里的数据是从数据库来的,更加符合开发。

模板继承

我们在访问一个网站,比如淘宝、京东时,我们会发现,其实每次实现页面跳转的时候,它的每一个页面的导航条都是相同的,那如果每一个页面都写同样的内容,你会不会觉得很繁琐啊,那么怎么办呢?

模板继承!

导航条:layout.html

{% load static %}<!doctype html>
<html lang="zh-CN">
<head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Title</title><!--rel="stylesheet"不能缺少 否则显示不出来样式 rel属性就是指明你链进来的对象是个什么东西 stylesheet表示是样式表--><link rel="stylesheet" href="{% static '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></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="true"><spanclass="glyphicon glyphicon-user"></span>个人信息<span class="caret"></span></a><ul class="dropdown-menu"><li><a href="#"><spanclass="glyphicon glyphicon-tree-conifer"></span>昵称:王晓曼</a></li><li role="separator" class="divider"></li><li><a href="#"><spanclass="glyphicon glyphicon-music"></span>个性签名:关关难过关关过,前路漫漫亦灿灿。</a></li></ul></li></ul></div></div>
</nav>
<div><!--设置居中--><div class="container">{% block content %}{% endblock %}</div>
</div>
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
</body>
</html>

添加页面:depart_add.html

{% extends 'layout.html' %}{% block content %}
<!--添加该页面内容-->
{% endblock %}

这样就可以了,当然,如果对其有多处改动,那也可以多加几个下面部分:

{% block 名称 %}
<!--添加该页面内容-->
{% endblock %}

测试结果如下:

depart_add

模板继承测试成功后,下面开始正式编写depart_add页面的编写了。

添加页面的主体是面板加表单设计。


{% extends 'layout.html' %}{% block content %}
<!--添加该页面内容-->
<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>
{% endblock %}


基础样式出来了后,我们就需要继续实现页面跳转。

def depart_add(request):# 如果是get请求if request.method == "GET":return render(request, "depart_add.html")# 如果是post请求 获取用户提交的数据title = request.POST.get("title")# 将数据加入到数据库 (此处默认数据都是合法的 后面用Form和ModelForm实现)models.Department.objects.create(title=title)# 重定向到用户列表return redirect("/depart/list/")

有没有发现把我们前面学习的东西都用起来了?

depart_delete

是不是很有成就感呢?下面来写一个删除吧,和上一篇案例中的删除大同小异奥!

首先要在depart_list中找到删除对应的位置,然后实现url跳转。

def depart_delete(request):# 获取需要删除的idnid = request.GET.get("nid")# 在数据库删除对应内容models.Department.objects.filter(id=nid).delete()# 重新返回列表展示页面return redirect("/depart/list/")

此处相当于更改为跳转到url为/depart/delete的位置,并且将用户id传递过来,在urls.py文件中的url - 视图函数对应中,可以知道其对应会执行depart_delete函数,于是获取参数、删除内容后,重定向到展示页面,整个流程一气呵成。

depart_edit

编辑页面,我们想想它长什么样子,其和我们新建部门页面应该差不多,但是差别在于,编辑的时候,你点进去的时候,部门的默认值是原来需要编辑的内容。

有了id有了一切,传id。


def depart_edit(request, nid):# 根据nid获取数据edit_data = models.Department.objects.filter(id=nid).first()return render(request, "depart_edit.html", {"edit_data": edit_data})

{% extends 'layout.html' %}{% block content %}
<!--添加该页面内容-->
<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="{{edit_data.title}}"></div><button type="submit" class="btn btn-primary">提交</button></form></div>
</div>
{% endblock %}




再来完善一下页面跳转。

def depart_edit(request, nid):# 如果是get请求if request.method == "GET":# 根据nid获取数据edit_data = models.Department.objects.filter(id=nid).first()return render(request, "depart_edit.html", {"edit_data": edit_data})# 获取用户更新的titletitle = request.POST.get("title")# 对数据库中进行修改models.Department.objects.filter(id=nid).update(title=title)# 重定向为部门列表return redirect("/depart/list/")



一直没看数据库,这里一起看一下吧~


记得刷新!空白部分,右键刷新!

项目用户管理

部门管理差不多了,下面来看用户管理吧!

用户管理可不一般,也就是字段多了点,那么在获取内容的时候也有很多小细节需要注意奥!

user_list

首先我们需要为数据库准备一些数据:

def user_orm(request):# 虽然在models.py中其为depart,但是实际上是depart_id,在操作的时候注意models.UserInfo.objects.create(name="王晓曼", password="123520", age=20, account=99999, create_time="2022-09-01",depart_id=1, gender=2)models.UserInfo.objects.create(name="王尚春", password="666666", age=49, account=199999, create_time="2000-01-01",depart_id=2, gender=1)models.UserInfo.objects.create(name="彭艳", password="111111", age=48, account=299999, create_time="2001-01-01",depart_id=3, gender=2)models.UserInfo.objects.create(name="王梦迪", password="131420", age=28, account=399999, create_time="2015-06-14",depart_id=6, gender=2)models.UserInfo.objects.create(name="黄伟", password="888888", age=33, account=499999, create_time="2012-12-31",depart_id=7, gender=1)return HttpResponse("成功")

然后在导航条里加上用户管理这一个标签。


用户列表,其实和部门列表差不多,只是字段可能不一样,先仿着部门列表写。

{% extends 'layout.html' %}{% block content %}
<!--添加该页面内容-->
<div style="margin-bottom:20px"><!--span后一个换行使得字体图标和文字有一点空隙--><a class="btn btn-primary" href="/user/add/"><span class="glyphicon glyphicon-plus-sign"></span>新建用户</a>
</div>
<!--面板+表格-->
<div><div class="panel panel-default"><div class="panel-heading"><span class="glyphicon glyphicon-th-list"></span>用户列表</div><!--可以直接在浏览器中选中元素 copy element--><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 data in data_list %}<tr><th scope="row">{{data.id}}</th><td>{{data.name}}</td><td>{{data.password}}</td><td>{{data.age}}</td><td>{{data.account}}</td><td>{{data.create_time}}</td><td>{{data.depart}}</td><td>{{data.gender}}</td><td><a class="btn btn-success btn-xs" href="#">编辑</a><a class="btn btn-danger btn-xs" href="#">删除</a></td></tr>{% endfor %}</tbody></table></div>
</div>
</div>
</div>
{% endblock %}

测试效果如下:

但是这样的效果肯定不好,所以我们需要在后端调整。

def user_list(request):data_list = models.UserInfo.objects.all()# 由于数据比较复杂 所以需要在后端进行调试数据格式 当然有可能前后端数据格式调整代码会不同 也会有局部更改for data in data_list:print(data.create_time.strftime("%Y-%m-%d"))return render(request, "user_list.html", {"data_list": data_list})


但是我们发现性别不是我们想要的展示数据,于是我们想起在定义表的时候,有一个gender_choices这个变量,那么怎么将数据展示成我们想要的呢?

def user_list(request):data_list = models.UserInfo.objects.all()# 由于数据比较复杂 所以需要在后端进行调试数据格式 当然有可能前后端数据格式调整代码会不同 也会有局部更改for data in data_list:# strftime("%Y-%m-%d")是后端将datetime类型转换为字符串形式print(data.create_time.strftime("%Y-%m-%d"))# 将元组套元组的类型 转换成 对应的字段print(data.get_gender_display())return render(request, "user_list.html", {"data_list": data_list})

那么depart_id怎么展示成对应的部门名称呢?

def user_list(request):data_list = models.UserInfo.objects.all()# 由于数据比较复杂 所以需要在后端进行调试数据格式 当然有可能前后端数据格式调整代码会不同 也会有局部更改for data in data_list:# strftime("%Y-%m-%d")是后端将datetime类型转换为字符串形式print(data.create_time.strftime("%Y-%m-%d"))# 将元组套元组的类型 转换成 对应的字段print(data.get_gender_display())# 拿取部门id对应的部门名称 我们知道在定义表的时候 定义的是depart 但是数据库给我们存的是depart_id 那么depart其实对应的是表的那一行的对象print(data.depart.title)return render(request, "user_list.html", {"data_list": data_list})


在后端测试好了后,移植到前端了。



是不是感觉很好呢?

user_add

其实添加用户和新建部门是一样的原理,但是可能字段会更多一点。

{% extends 'layout.html' %}{% block content %}
<!--添加该页面内容-->
<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"></div><div class="form-group"><label>密码</label><input type="text" class="form-control" placeholder="密码" name="password"></div><div class="form-group"><label>年龄</label><input type="text" class="form-control" placeholder="年龄" name="age"></div><div class="form-group"><label>余额</label><input type="text" class="form-control" placeholder="余额" name="account"></div><div class="form-group"><label>入职时间</label><input type="text" class="form-control" placeholder="入职时间" name="create_time"></div><div class="form-group"><label>部门</label><select class="form-control" name="depart">{% for data in depart_list %}<option value="{{data.id}}">{{data.title}}</option>{% endfor %}</select></div><div class="form-group"><label>性别</label><select class="form-control" name="gender">{% for item in gender_choices %}<option value="{{item.0}}">{{item.1}}</option>{% endfor %}</select></div><button type="submit" class="btn btn-primary">提交</button></form></div>
</div>
{% endblock %}
def user_add(request):# 拿到性别元组 和 部门信息gender_choices = models.UserInfo.gender_choicesdepart_list = models.Department.objects.all()# 如果是get请求if request.method == "GET":return render(request, "user_add.html", {"gender_choices": gender_choices, "depart_list": depart_list})# 如果是post请求 获取用户提交的数据name = request.POST.get("name")password = request.POST.get("password")age = request.POST.get("age")account = request.POST.get("account")create_time = request.POST.get("create_time")depart = request.POST.get("depart")gender = request.POST.get("gender")# 将数据加入到数据库 (此处默认数据都是合法的 后面用Form和ModelForm实现)models.UserInfo.objects.create(name=name, password=password, age=age, account=account, create_time=create_time,depart_id=depart, gender=gender)# 重定向到用户列表return redirect("/user/list/")



Form和ModelForm

有没有觉得如果字段很多的话,这也太复杂了吧!

没关系,Django给我们提供了Form和ModelForm奥,一起先来看看他们的基本用法吧!

Form

ModelForm


当然也支持自定义字段和Model字段一起!

user_add(ModelForm)

为了区分,我们首先在用户列表中,新增加一个按钮。



views.py中增加如下:

from django import formsclass UserModelForm(forms.ModelForm):class Meta:model = models.UserInfofields = ["name", "password", "age"]def user_model_form_add(request):form = UserModelForm()return render(request, "user_model_form_add.html", {"form": form})


先测试基本数据(不考虑样式):

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form method="post">{% csrf_token %}<!--form.字段.label表示对应的中文名-->{{form.name.label}}:{{form.name}}{{form.password.label}}:{{form.password}}{{form.age.label}}:{{form.age}}
</form>
</body>
</html>


对form进行循环:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form method="post">{% csrf_token %}<!--form.字段.label表示对应的中文名--><!--{{form.name.label}}:{{form.name}}{{form.password.label}}:{{form.password}}{{form.age.label}}:{{form.age}}-->{% for field in form %}{{field.label}}:{{field}}{% endfor %}
</form>
</body>
</html>


剩下的字段都加上,看一下效果:



有没有发现其他的很方便,但是depart怎么肥四?!

首先我们没有写verbose_name,所以直接把字段名写出来了。

其次这个为对象,所以直接输出了对象。


搞定!

现在集成到bootstrap中!

{% extends 'layout.html' %}{% block content %}
<!--添加该页面内容-->
<div class="panel panel-default"><div class="panel-heading"><h3 class="panel-title">新建ModelForm用户</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>
{% endblock %}


但是长得有点丑啊!



把所有的都加上:

from django import formsclass UserModelForm(forms.ModelForm):class Meta:model = models.UserInfofields = ["name", "password", "age", "account", "create_time", "depart", "gender"]# 插件# widgets = {#     "name": forms.TextInput(attrs={"class": "form-control"})# }def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)for name, field in self.fields.items():field.widget.attrs = {"class": "form-control", "placeholder": field.label}def user_model_form_add(request):form = UserModelForm()return render(request, "user_model_form_add.html", {"form": form})


完善POST后的相关处理:

def user_model_form_add(request):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():# 如果数据合法  保存到数据库print(form.cleaned_data)form.save()return redirect("/user/list/")else:print(form.errors)return render(request, "user_model_form_add.html", {"form": form})


怎么将提示变成中文呢?

LANGUAGE_CODE = 'zh-hans'



如果对于姓名字段,添加一些限制呢?



正确的添加:

总而言之:ModelForm针对操作数据库某个表,其他还是Form。

user_edit



def user_edit(request, nid):if request.method == "GET":# 根据id去数据库获取编辑的那一行row_object = models.UserInfo.objects.filter(id=nid).first()form = UserModelForm(instance=row_object)return render(request, "user_edit.html", {"form": form})# 完成编辑后保存到当前对象中 而不是新增一个用户 (该行可放在最上面)row_object = models.UserInfo.objects.filter(id=nid).first()# 用Post提交的数据 进行数据校验form = UserModelForm(data=request.POST, instance=row_object)if form.is_valid():# 如果数据合法  保存到数据库print(form.cleaned_data)# 默认保存的是用户输入的所有数据 如果想要再保存用户输入的额外的值# form.instance.字段名=值form.save()return redirect("/user/list/")else:print(form.errors)return render(request, "user_edit.html", {"form": form})

页面就和用户添加的页面差不多,只需要修改标题。

{% extends 'layout.html' %}{% block content %}
<!--添加该页面内容-->
<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>
{% endblock %}

user_delete



叮咚,完成!

基于Pycharm的Django学习 —— 项目实战(Form和ModelForm)相关推荐

  1. 基于Pycharm的Django学习 —— 用户管理小demo

    自从学了Django之后,我可真粉了银角大王武沛齐,怎么说呢,还挺感慨,好好学习就对了. 学以致用,学以致用,学了Django中的ORM,怎么能够不写一个小案例呢? 基于Pycharm的Django学 ...

  2. 深度学习项目实战——1.基于WordCloud词云生成

    深度学习项目实战--1.基于WordCloud词云生成 准备 安装依赖库 pip install wordcloud matplotlib jieba pillow WordCloud()可选的参数 ...

  3. 【PyTorch深度学习项目实战100例】—— 基于ResNet50实现多目标美味蛋糕图像分类 | 第51例

    前言 大家好,我是阿光. 本专栏整理了<PyTorch深度学习项目实战100例>,内包含了各种不同的深度学习项目,包含项目原理以及源码,每一个项目实例都附带有完整的代码+数据集. 正在更新 ...

  4. 【PyTorch深度学习项目实战100例】—— 基于CNN实现书法字体风格识别任务 | 第62例

    前言 大家好,我是阿光. 本专栏整理了<PyTorch深度学习项目实战100例>,内包含了各种不同的深度学习项目,包含项目原理以及源码,每一个项目实例都附带有完整的代码+数据集. 正在更新 ...

  5. 【PyTorch深度学习项目实战100例】—— 基于聚类算法完成航空公司客户价值分析任务 | 第18例

    前言 大家好,我是阿光. 本专栏整理了<PyTorch深度学习项目实战100例>,内包含了各种不同的深度学习项目,包含项目原理以及源码,每一个项目实例都附带有完整的代码+数据集. 正在更新 ...

  6. 【PyTorch深度学习项目实战100例】—— 基于逻辑回归方法完成垃圾邮件过滤任务 | 第22例

    前言 大家好,我是阿光. 本专栏整理了<PyTorch深度学习项目实战100例>,内包含了各种不同的深度学习项目,包含项目原理以及源码,每一个项目实例都附带有完整的代码+数据集. 正在更新 ...

  7. 深度学习项目实战-关键点定位视频课程

    课程目标 快速掌握如何使用caffe框架完成一个深度学习的实际项目 适用人群 深度学习爱好者,全民皆可入门 课程简介 深度学习项目实战-关键点定位课程以人脸关键点检测为背景,选择多阶段检测的网络架构, ...

  8. 【项目】bxg基于SaaS的餐掌柜项目实战(2023)

    基于SaaS的餐掌柜项目实战 餐掌柜是一款基于SaaS思想打造的餐饮系统,采用分布式系统架构进行多服务研发,共包含4个子系统,分别为平台运营端.管家端(门店).收银端.小程序端,为餐饮商家打造一站式餐 ...

  9. 【PyTorch深度学习项目实战100例目录】项目详解 + 数据集 + 完整源码

    前言 大家好,我是阿光. 本专栏整理了<PyTorch深度学习项目实战100例>,内包含了各种不同的深度学习项目,包含项目原理以及源码,每一个项目实例都附带有完整的代码+数据集. 正在更新 ...

最新文章

  1. shell脚本调试技术
  2. CentOS 7 安装部署 cassandra作为kairosdb的数据存储
  3. RabbitMQ之消息持久化
  4. 驾照考试(科目三-大路)
  5. 【Android工具】更新WPS全功能正版授权无广告版
  6. G6 图可视化引擎——入门教程——前言
  7. 用户退出登录清空cookie
  8. oracle实列关闭,Oracle单实例+ASM启动与关闭
  9. amp 调用链_调用链选型之Zipkin,Pinpoint,SkyWalking,CAT
  10. JavaScript 事件机制
  11. Linux系统信息与系统资源
  12. 如何判断一个new出来的空对象
  13. 【SpringClould】Spring Cloud Eureka源码分析
  14. 谷歌浏览器怎么查找和改变编码格式
  15. 【莫队算法】【权值分块】bzoj3585 mex
  16. [源码]C# to SQL 的翻译器.net 1.1版
  17. Sentaurus入门(3):sde
  18. 【定位】纯激光导航定位丢失/漂移问题的优化方案及思考
  19. Log4j2-Log4j 2介绍及使用
  20. 职场保护自己利益的技巧,你知道多少?

热门文章

  1. 店盈通:2021年巨头押注末端,同城即配提速
  2. 互联网玄学的“造神”奇迹还能持续多久?
  3. js按钮确认删除提示
  4. 编程入门:如何正确认识编程?除了高薪,我再告诉你一些秘密!
  5. 宜宾地震,物联网发挥了怎样的作用?
  6. 留言赠书|因果推断与机器学习,终于有本书能讲明白啦!
  7. 月收入15k在上海的生活
  8. 读《读大学,究竟读什么》读后感
  9. 【Python爬虫】按时爬取京东几类自营手机型号价格参数并存入数据库
  10. Ubuntu16.04上NVIDIA Titan显卡出现屏幕分辨率失常