资产信息功能添加
目录
1.创建表格
2.页面展示
3.新增和修改
4.删除
这篇文章的内容, 就是在前面做的基础上, 新增一个资产管理功能, 其实就和之前的部门信息还有员工信息差不多的, 但是这篇文章里面, 会有些细节的地方, 和之前的不太一样。那下面我们就开始讲述这篇文章的内容了!!!
一、创建表格
我们需要创建一个叫Assets的表格:
代码:
models.py:
from django.db import models
# Create your models here.
# 以前创建过的Department部门表
class Department(models.Model):
title = models.CharField(verbose_name="部门名称", max_length=255)
def __str__(self):
return self.title
# 以前创建过的UserInfo员工表
class UserInfo(models.Model):
name = models.CharField(verbose_name="姓名", max_length=255)
gender_choices = (
(1, "男"), (2, "女")
)
gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
salary = models.IntegerField(verbose_name="薪水")
age = models.IntegerField(verbose_name="年龄")
create_time = models.DateField(verbose_name="入职时间")
department = models.ForeignKey(verbose_name="部门", max_length=255, to="Department", to_field="id",
on_delete=models.CASCADE, null=True, blank=True)
def __str__(self):
return self.name
# 创建Assets表格, 资产表
class Assets(models.Model):
mobile = models.CharField(verbose_name="手机号", max_length=11)
status_code_choice = (
(1, "已使用"),
(2, "未使用")
)
status = models.SmallIntegerField(verbose_name="状态", choices=status_code_choice)
create_time = models.DateField(verbose_name="创建时间")
user = models.ForeignKey(to="UserInfo", to_field="id", verbose_name="使用者", on_delete=models.SET_NULL, null=True, blank=True)
price = models.CharField(verbose_name="价格", max_length=10)
然后打开对应目录的终端:
分别输入以下指令:
python manage.py makemigrations
python manage.py migrate
这些内容, 在之前的地方就已经讲过, 所以这里不再详细讲述。
二、页面展示
我们在templates里面新增assets文件夹, 然后在里面创建assets_list.html
assets_list.html:
{% extends "index/model_tmp.html" %}
{% block content %}
<div class="container">
<a href="/assets/add/" class="btn btn-success">添加信息</a>
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">资产表</h3>
</div>
<div class="panel-body">
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>手机号</th>
<th>状态</th>
<th>创建时间</th>
<th>使用者</th>
<th>价格</th>
</tr>
</thead>
<tbody>
{% for data in assets_list %}
<tr>
<th scope="row">{{ data.id }}</th>
<td>{{ data.mobile }}</td>
{% if data.status == 1 %}
<td style="color: green">{{ data.get_status_display }}</td>
{% else %}
<td style="color: red">{{ data.get_status_display }}</td>
{% endif %}
<td>{{ data.create_time|date:"Y-m-d" }}</td>
<td>{{ data.user.name }}</td>
<td>{{ data.price }}</td>
<td style="color: green">
<a href="/assets/{{ data.id }}/modify"><span style="color: green;" class="glyphicon glyphicon-pencil" aria-hidden="true"></span></a>
<a href="/assets/{{ data.id }}/del/"><span style="color: red;" class="glyphicon glyphicon-trash" aria-hidden="true"></span></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
这里有个细节, 就是在td里面有if判断, 因为状态只有两个值, 分别是已使用和未使用, 如果是已使用, 那就把文字的颜色变为绿色反之就变为红色。<td>{{ data.create_time|date:"Y-m-d" }}</td>
这块代码, 就是设置在页面里面展示的时间的格式(用年-月-日来展示)
在views文件夹里面, 新建一个assets.py文件
assets.py:
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.shortcuts import render, redirect
from django import forms
from project_one import models
# Create your views here.
def assets(request):
assets_list = models.Assets.objects.all()
return render(request, "assets/assets_list.html", {"assets_list": assets_list})
设置路由:
urls.py:
"""project_simple URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from project_one.views import depart, user, assets
urlpatterns = [
# path('admin/', admin.site.urls),
path("", depart.index),
# 部门展示页面的路由
path("depart/", depart.depart),
path("depart/add/", depart.add_depart),
path("depart/<int:nid>/modify/", depart.depart_modify),
path("depart/<int:nid>/del/", depart.del_depart),
# 员工展示页面的路由
path("user/", user.user_info),
path("user/add/", user.user_add),
path("user/<int:nid>/modify/", user.user_modify),
path("user/<int:nid>/del/", user.user_del),
path("user/add/modelform", user.user_add_modelform),
path("user/<int:nid>/modify/modelform", user.user_modify_modelform),
# 资产展示页面的路由
path("assets_list/", assets.assets)
]
三、新增和修改
编辑views文件夹下面的assets.py:
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.shortcuts import render, redirect
from django import forms
from project_one import models
# Create your views here.
def assets(request):
assets_list = models.Assets.objects.all()
return render(request, "assets/assets_list.html", {"assets_list": assets_list})
class AssetsAddModelForm(forms.ModelForm):
# validators是手机号格式校验, 里面是校验规则, 需要用到RegexValidator函数
# RegexValidator函数需要在导入的时候写:from django.core.validators import RegexValidator
mobile = forms.CharField(label="手机号", validators=[RegexValidator(r"^1[3-9]\d{9}")])
class Meta:
model = models.Assets
fields = "__all__"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for name, field in self.fields.items():
# 给前端的input输入框或select选择框, 增加属性, 让界面更美观。
field.widget.attrs = {"class": "form-control"}
def clean_mobile(self):
mobile = self.cleaned_data["mobile"]
# 在数据表当中判断是否存在, filter里面的mobile代表以电话号码为判断依据
# 因为我们添加数据的时候, 手机号不能重复添加, 所以需要判断是否存在。
exists = models.Assets.objects.filter(mobile=mobile).exists()
if exists:
# 如果手机号已存在, 则抛出异常
# 这个异常函数, 在导入的时候写:from django.core.exceptions import ValidationError
raise ValidationError("手机号已存在")
return mobile
def assets_add(request):
if request.method == "GET":
title = "添加资产"
form = AssetsAddModelForm()
return render(request, "assets/assets_modelform.html", {"form": form, "title": title})
form = AssetsAddModelForm(request.POST)
if form.is_valid():
form.save()
return redirect("/assets_list/")
return render(request, "assets/assets_modelform.html", {"form": form})
class AssetsModifyModelForm(forms.ModelForm):
# 禁止编辑价格那栏输入框
price = forms.CharField(disabled=True, label="价格")
class Meta:
model = models.Assets
fields = "__all__"
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):
mobile = self.cleaned_data["mobile"]
# self.instance.pk这个代表获取当前数据的id
exists = models.Assets.objects.exclude(id=self.instance.pk).filter(mobile=mobile).exists()
if exists:
raise ValidationError("手机号已存在")
return mobile
def assets_modify(request, nid):
data_list = models.Assets.objects.filter(id=nid).first()
if request.method == "GET":
title = "修改数据"
form = AssetsModifyModelForm(instance=data_list)
return render(request, "assets/assets_modelform.html", {"form": form, "title": title})
form = AssetsModifyModelForm(request.POST, instance=data_list)
if form.is_valid():
form.save()
return redirect("/assets_list/")
return render(request, "assets/assets_modelform.html", {"form": form})
新增数据的modelform里面的细节:
1.mobile = forms.CharField(label=“手机号”, validators=[RegexValidator(r"^1[3-9]\d{9}")])这行代码里面, validators就是通过正则表达式来进行校验手机号的格式是否正确。2.clean_mobile这个是重写了系统里面的函数,mobile = self.cleaned_data[“mobile”]这个就是用于获取手机号码。在我们添加数据的时候, 需要判断创建数据当中的手机号是否已经被创建过, 不能重新添加相同的手机号。exists = models.Assets.objects.filter(mobile=mobile).exists()这行代码就是判断手机号是否已经存在。最后不要忘返回手机号的值return mobile。
修改数据的modelform里面的细节:
1.在修改数据的界面里, 价格那栏是不允许修改的, 用price = forms.CharField(disabled=True, label=“价格”)这行代码去实现。field.widget.attrs = {"class": "form-control"}
和mobile = self.cleaned_data["mobile"]
这两行代码, 和添加功能里面的意思是一样的, 在修改里面, 唯一不一样的地方就是exists的判断方式不一样, 这里是exists = models.Assets.objects.exclude(id=self.instance.pk).filter(mobile=mobile).exists()
里面多了个exclude(id=self.instance.pk)
是因为我们在修改数据的时候, 不仅要满足手机号不重复, 还要满足修改数据里, 号码不变的情况能够替换使用者, 所以需要在修改数据的时候, 去除自己本身的电话号码并判断是否有号码重复(这里的self.instance.pk就代表是要修改那行数据的id)。(这里可能稍微有点儿绕, 我们可以举个例子去说明)。例子:比如原来的数据是: 电话:13366667777, 使用者是张三, 此时此刻, 在数据库里面没有电话重复, 然后在修改数据的时候, 我们想要把使用者改下但不改电话, 电话仍是13366667777, 使用者改为李四, 这种情况, 正常来讲是允许被修改的, 不过程序它会在数据库里面查找所有的电话号码包括本身的号码也会被查询, 然后发现我修改数据里面的手机号存在数据库, 自然会判断电话号码已存在, 不能修改数据, 所以我们需要用到排除自己那行数据的电话号码的同时再去数据库查找信息, 这样在修改数据的时候, 系统就查找不出来相同的手机号码了。
在templates里面的assets文件夹里面, 创建assets_modelform.html文件
assets_modelform.html:
{% extends "index/model_tmp.html" %}
{% load static %}
{% block css %}
<link rel="stylesheet" href="{% static 'css/layui.css' %}">
{% endblock %}
{% block content %}
<div class="container">
<h1>{{ title }}</h1>
<form method="post">
{% csrf_token %}
{% for filed in form %}
{# filed.label这里面就是获取我们在models.py里面创建表格里面的每一个字段里面有个verbose_name这个参数的值 #}
<label for="exampleInputEmail1">{{ filed.label }}</label>
{{ filed }}
{# 展示错误信息 #}
<span style="color: red">{{ filed.errors.0 }}</span>
<br>
{% endfor %}
<button type="submit" class="btn btn-success">提交</button>
</form>
</div>
{% endblock %}
{% block js %}
<script src="{% static "js/layui.js" %}"></script>
<script>
layui.use(function () {
var laydate = layui.laydate;
// 渲染
laydate.render({
// 这个id是员工入职时间的那个input输入框的id, 我们使用了modelform, 它会自动给我们每一个input都会生成一个id,
// 格式为id_数据库字段名, 我们数据库员工表格里面的员工入职时间的那个字段是create_time, 所以id是id_create_time。
elem: '#id_create_time'
});
});
</script>
{% endblock %}
新增和修改的前端页面, 都是用assets_modelform.html。
urls.py:
"""project_simple URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from project_one.views import depart, user, assets
urlpatterns = [
# path('admin/', admin.site.urls),
path("", depart.index),
path("depart/", depart.depart),
path("depart/add/", depart.add_depart),
path("depart/<int:nid>/modify/", depart.depart_modify),
path("depart/<int:nid>/del/", depart.del_depart),
path("user/", user.user_info),
path("user/add/", user.user_add),
path("user/<int:nid>/modify/", user.user_modify),
path("user/<int:nid>/del/", user.user_del),
path("user/add/modelform", user.user_add_modelform),
path("user/<int:nid>/modify/modelform", user.user_modify_modelform),
path("assets_list/", assets.assets),
path("assets/add/", assets.assets_add),
path("assets/<int:nid>/modify/", assets.assets_modify)
]
四、删除数据
删除数据的代码很简单, 我相信大家都可以闭着眼睛都能写出来了。
def assets_del(request, nid):
models.Assets.objects.filter(id=nid).delete()
return redirect("/assets_list/")
通过id号来删除数据。
完整的assets.py代码:
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.shortcuts import render, redirect
from django import forms
from project_one import models
# Create your views here.
def assets(request):
assets_list = models.Assets.objects.all()
return render(request, "assets/assets_list.html", {"assets_list": assets_list})
class AssetsAddModelForm(forms.ModelForm):
# validators是手机号格式校验, 里面是校验规则, 需要用到RegexValidator函数
# RegexValidator函数需要在导入的时候写:from django.core.validators import RegexValidator
mobile = forms.CharField(label="手机号", validators=[RegexValidator(r"^1[3-9]\d{9}")])
class Meta:
model = models.Assets
fields = "__all__"
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):
mobile = self.cleaned_data["mobile"]
# 在数据表当中判断是否存在, filter里面的mobile代表以电话号码为判断依据
# 因为我们添加数据的时候, 手机号不能重复添加, 所以需要判断是否存在。
exists = models.Assets.objects.filter(mobile=mobile).exists()
if exists:
# 如果手机号已存在, 则抛出异常
# 这个异常函数, 在导入的时候写:from django.core.exceptions import ValidationError
raise ValidationError("手机号已存在")
return mobile
def assets_add(request):
if request.method == "GET":
title = "添加资产"
form = AssetsAddModelForm()
return render(request, "assets/assets_modelform.html", {"form": form, "title": title})
form = AssetsAddModelForm(request.POST)
if form.is_valid():
form.save()
return redirect("/assets_list/")
return render(request, "assets/assets_modelform.html", {"form": form})
class AssetsModifyModelForm(forms.ModelForm):
# 禁止编辑价格那栏输入框
price = forms.CharField(disabled=True, label="价格")
class Meta:
model = models.Assets
fields = "__all__"
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):
mobile = self.cleaned_data["mobile"]
# self.instance.pk这个代表获取当前数据的id
exists = models.Assets.objects.exclude(id=self.instance.pk).filter(mobile=mobile).exists()
if exists:
raise ValidationError("手机号已存在")
return mobile
def assets_modify(request, nid):
data_list = models.Assets.objects.filter(id=nid).first()
if request.method == "GET":
title = "修改数据"
form = AssetsModifyModelForm(instance=data_list)
return render(request, "assets/assets_modelform.html", {"form": form, "title": title})
form = AssetsModifyModelForm(request.POST, instance=data_list)
if form.is_valid():
form.save()
return redirect("/assets_list/")
return render(request, "assets/assets_modelform.html", {"form": form})
def assets_del(request, nid):
models.Assets.objects.filter(id=nid).delete()
return redirect("/assets_list/")
完整的路由urls.py代码:
"""project_simple URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from project_one.views import depart, user, assets
urlpatterns = [
# path('admin/', admin.site.urls),
path("", depart.index),
path("depart/", depart.depart),
path("depart/add/", depart.add_depart),
path("depart/<int:nid>/modify/", depart.depart_modify),
path("depart/<int:nid>/del/", depart.del_depart),
path("user/", user.user_info),
path("user/add/", user.user_add),
path("user/<int:nid>/modify/", user.user_modify),
path("user/<int:nid>/del/", user.user_del),
path("user/add/modelform", user.user_add_modelform),
path("user/<int:nid>/modify/modelform", user.user_modify_modelform),
path("assets_list/", assets.assets),
path("assets/add/", assets.assets_add),
path("assets/<int:nid>/modify/", assets.assets_modify),
path("assets/<int:nid>/del/", assets.assets_del),
]
完善templates/index/model_tmp.html文件里面的代码:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'css/bootstrap.css' %}">
{% block css %}
{% endblock %}
</head>
<body>
<div 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 class="active"><a href="/depart/">部门页面</a></li>
<li class="active"><a href="/user/">员工页面</a></li>
{# 实现资产页面以及相应功能 #}
<li class="active"><a href="/assets_list/">资产页面</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="#">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>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Nathan<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="#">退出登录</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</div>
{% block content %}
{% endblock %}
<script src="{% static 'js/jquery3.7.1.js' %}"></script>
<script src="{% static 'js/bootstrap.js' %}"></script>
{% block js %}
{% endblock %}
</body>
</html>
运行结果:
点击资产页面:
点击添加信息按钮:
填入相应数据:
点击提交。
成功新增数据。
我们用同样的方法, 再新增一条数据:
修改数据:
我们就修改李四的数据看看:
修改电话为13366669988, 时间改为2024年12月16日, 状态改为已使用。
修改过后:
以上就是Django资产信息功能添加的所有内容了, 如果有哪里不懂的地方,可以把问题打在评论区, 欢迎大家在评论区交流!!!
如果我有写错的地方, 望大家指正, 也可以联系我, 让我们一起努力, 继续不断的进步.
学习是个漫长的过程, 需要我们不断的去学习并掌握消化知识点, 有不懂或概念模糊不理解的情况下,一定要赶紧的解决问题, 否则问题只会越来越多, 漏洞也就越老越大.
人生路漫漫, 白鹭常相伴!!!