1、新建项目&整合

目录

  • 1、新建项目&整合
    • (1)删除templates目录
    • (2)修改setting.py模板路径
    • (3)下载第三方库`pip install mysqlclient-1.4.6-cp37-cp37m-win_amd64.whl`
    • (4)新建数据库
    • (5)修改setting.py数据库配置
    • (6)修改setting.py中文配置
    • (7)在工具->manage.py中新建app
    • (8)在setting.py注册app
    • (9)将静态文件、模板、分页组件拷贝过来
    • (10)在 app01->models.py 中创建数据表
    • (11)迁移数据表
    • (12)插入一些测试数据
    • (13)当前项目文件结构+代码
    • (14)Bootstrap样式父类
    • (15)项目文件重构
(1)删除templates目录
(2)修改setting.py模板路径
(3)下载第三方库pip install mysqlclient-1.4.6-cp37-cp37m-win_amd64.whl
(4)新建数据库
create database pretty_manage_system default charset=utf8;
(5)修改setting.py数据库配置
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'pretty_manage_system','USER': 'root','PASSWORD': '123456','HOST': '127.0.0.1','PORT': '3306',}
}
(6)修改setting.py中文配置
LANGUAGE_CODE = 'zh-hans'
(7)在工具->manage.py中新建app

(8)在setting.py注册app
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','app01.apps.App01Config'
]
(9)将静态文件、模板、分页组件拷贝过来

(10)在 app01->models.py 中创建数据表
from django.db import models# Create your models here.
class Department(models.Model):"""部门表"""title = models.CharField(verbose_name='部门标题',max_length=32)#verbose_name是给自己看的注释,不会影响数据库#输出对象时的返回值def __str__(self):return self.titleclass 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.DateField(verbose_name='入职时间')depart = models.ForeignKey(verbose_name='所在部门',to="Department", to_field="id",on_delete=models.CASCADE)gender_choices=((1, "男"),(2, "女"),)gender = models.SmallIntegerField(verbose_name="性别",choices=gender_choices)class PrettyNum(models.Model):"""靓号表"""mobile = models.CharField(verbose_name="手机号",max_length=32)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_chioces =((1, "已占用"),(0, "未占用"),)status = models.SmallIntegerField(verbose_name="状态",choices=status_chioces,default=0)
(11)迁移数据表

在工具->运行manage.py中执行命令①makemigrations执行命令②migrate
查看数据库中的数据表:

(12)插入一些测试数据

部门表

 insert into app01_department(title) value("IT部门"),("销售部门");

员工表

 insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id)values("刘东","123",23,100.68,"2022-09-01",1,1);insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id)values("刘北","123",22,100.68,"2022-09-01",1,2);

靓号表

insert into app01_prettynum(mobile,price,level,status)values("138521112222",10000,2,0);
insert into app01_prettynum(mobile,price,level,status)values("138521111111",10000,2,0);
insert into app01_prettynum(mobile,price,level,status)values("155521112222",10000,2,0);
(13)当前项目文件结构+代码


template.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>{% block title_content %}{% endblock %}</title><link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
</head>
<body>
<!--导航-->
<div class="bs-example" data-example-id="inverted-navbar"><nav class="navbar navbar-inverse"><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-9" 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-9"><ul class="nav navbar-nav"><li><a href="/depart/list/">部门管理</a></li><li><a href="/user/list/">用户管理</a></li><li><a href="/pretty/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="#">Action</a></li><li><a href="#">Another action</a></li><li><a href="#">Something else here</a></li><li role="separator" class="divider"></li><li><a href="#">Separated link</a></li></ul></li></ul></div><!-- /.navbar-collapse --></div><!-- /.container-fluid --></nav>
</div>{% block content %}{% endblock %}<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>

depart_list

{% extends 'template.html' %}
{% block content %}<div><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 queryset %}<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><ul class="pagination">{{ page_string }}</ul></div></div>
{% endblock %}

depart_add

{% extends 'template.html' %}
{% block content %}<div><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"><!--action可以不写,因为不写的话提交的是当前地址-->{% 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></div>
{% endblock %}

depart_edit

{% extends 'template.html' %}
{% block content %}<div><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"><!--action可以不写,因为不写的话提交的是当前地址-->{% 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></div>
{% endblock %}

user_list

{% extends 'template.html' %}
{% block content %}<div><div class="container"><!--按钮--><div style="margin-bottom: 10px"><a class="btn btn-success" href="/user/add/"><span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>新建用户</a><a class="btn btn-success" href="/user/modelform/add/"><span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>新建用户ModelForm</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><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.name }}</td><td>{{ obj.password }}</td><td>{{ obj.age }}</td><td>{{ obj.account }}</td><!--模板里面无括号,所以格式化参数也不能有 <td>{ obj.create_time.strftime("%Y-%m-%d") }</td>--><td>{{ obj.create_time|date:"Y-m-d" }}</td><!--模板中参数无括号,括号是自动加的<td>{ obj.get_gender_display() }</td>--><td>{{ obj.get_gender_display }}</td><td>{{ obj.depart.title }}</td><td><a class="btn btn-primary btn-xs" href="/user/{{ obj.id }}/edit/">编辑</a><a class="btn btn-danger btn-xs" href="/user/delete/?uid={{ obj.id }}">删除</a></td></tr>{% endfor %}</tbody></table></div><ul class="pagination">{{ page_string }}</ul></div></div>
{% endblock %}

user_add

{% extends 'template.html' %}
{% block content %}<div><div class="container"><div class="panel panel-default"><div class="panel-heading"><h3 class="panel-title"> 新建用户 </h3></div><div class="panel-body"><!--表单--><!--action可以不写,因为不写的话提交的是当前地址--><form method="post" novalidate><!--novalidate:表示不采用views函数里的校验,采用自己写的页面校验-->{% csrf_token %}{% for obj in form %}<div class="form-group"><label> {{ obj.label }} </label>{{ obj }}<span style="color:red"> {{ obj.errors.0 }}</span><!--错误信息以列表形式存储--><!--<input type="text" class="form-control" placeholder="姓名" name="name"/>--></div>{% endfor %}<button type="submit" class="btn btn-primary"> 提交</button></form></div></div></div></div>
{% endblock %}

user_edit

{% extends 'template.html' %}
{% block content %}<div><div class="container"><div class="panel panel-default"><div class="panel-heading"><h3 class="panel-title"> 编辑用户 </h3></div><div class="panel-body"><!--表单--><!--action可以不写,因为不写的话提交的是当前地址--><form method="post" novalidate><!--novalidate:表示不采用views函数里的校验,采用自己写的页面校验-->{% csrf_token %}{% for obj in form %}<div class="form-group"><label> {{ obj.label }} </label>{{ obj }}<span style="color:red"> {{ obj.errors.0 }}</span><!--错误信息以列表形式存储--><!--<input type="text" class="form-control" placeholder="姓名" name="name"/>--></div>{% endfor %}<button type="submit" class="btn btn-primary"> 提交</button></form></div></div></div></div>
{% endblock %}

prety_list

{% extends 'template.html' %}
{% block title_content %}靓号列表
{% endblock %}{% block content %}<div class="container"><!--按钮--><div style="margin-bottom: 0px" class="left"><a class="btn btn-success" href="/pretty/add/"><span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>添加靓号</a><!--搜索--><a><form class="navbar-form navbar-right" method="get" action="/pretty/list/"><div class="form-group"><input type="text" class="form-control" placeholder="输入号码" name="q" value="{{ value }}"></div><button type="submit" class="btn btn-default">搜索</button></form></a></div><br><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><th>ID</th><th>号码</th><th>价格</th><th>级别</th><th>状态</th><th>操作</th></thead><tbody>{% for qurey in qureyset %}<tr><th>{{ qurey.id }}</th><td>{{ qurey.mobile }}</td><td>{{ qurey.price }}</td><td>{{ qurey.get_level_display }}</td><td>{{ qurey.get_status_display }}</td><td><a class="btn btn-primary btn-xs" href="/pretty/{{ qurey.id }}/edit">编辑</a><a class="btn btn-danger btn-xs" href="/pretty/delete/?nid={{ qurey.id }}">删除</a></td></tr>{% endfor %}</tbody></table></div><!--分页组件--><div class="clearfix"><ul class="pagination">{{ page_string }}</ul></div></div>
{% endblock %}

prety_add

{% extends 'template.html' %}
{% block content %}<div><div class="container"><div class="panel panel-default"><div class="panel-heading"><h3 class="panel-title"> 新建靓号 </h3></div><div class="panel-body"><!--表单--><!--action可以不写,因为不写的话提交的是当前地址--><form method="post" novalidate><!--novalidate:表示不采用views函数里的校验,采用自己写的页面校验-->{% csrf_token %}{% for obj in form %}<div class="form-group"><label> {{ obj.label }} </label>{{ obj }}<span style="color:red"> {{ obj.errors.0 }}</span><!--错误信息以列表形式存储--><!--<input type="text" class="form-control" placeholder="姓名" name="name"/>--></div>{% endfor %}<button type="submit" class="btn btn-primary"> 提交</button></form></div></div></div></div>
{% endblock %}

prety_edit

{% extends 'template.html' %}
{% block content %}<div><div class="container"><div class="panel panel-default"><div class="panel-heading"><h3 class="panel-title"> 编辑靓号 </h3></div><div class="panel-body"><!--表单--><!--action可以不写,因为不写的话提交的是当前地址--><form method="post" novalidate><!--novalidate:表示不采用views函数里的校验,采用自己写的页面校验-->{% csrf_token %}{% for obj in form %}<div class="form-group"><label> {{ obj.label }} </label>{{ obj }}<span style="color:red"> {{ obj.errors.0 }}</span><!--错误信息以列表形式存储--><!--<input type="text" class="form-control" placeholder="姓名" name="name"/>--></div>{% endfor %}<button type="submit" class="btn btn-primary"> 提交</button></form></div></div></div></div>
{% endblock %}

pagination.py

"""
【自定义分页组件】
以后如果想要复用这个分页组件,需要做的事情如下:
(1)在视图函数中
def pretty_list(request):#1、根据需求筛选数据queryset = models.PrettyNum.objects.all()#2、实例化分页对象page_object = Pagination(request,queryset)#参数字典contex = {"qureyset": page_object.page_queryset,  #分完页的数据"page_string": page_object.html(),      #生成的页码}#返回值return render(request, "pretty_list.html", contex)
(2)在html页面中处理数据{% for qurey in qureyset %}obj.xxx{% endfor %}分页样式<ul class="pagination">{{ page_string }}</ul>
"""
from django.utils.safestring import mark_safe
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中传递的获取分页的参数,例如:/pretty/list/?page=1:param plus:显示当前页的前或后几页(页码)"""#获取URLfrom django.http.request import QueryDictimport copyquery_dict = copy.deepcopy(request.GET)query_dict._mutable = Trueself.query_dict = query_dictself.page_param = page_param#获取当前页page = request.GET.get(page_param,"1")#判断是否是十进制数if page.isdecimal():page=int(page)else:page=1self.page = pageself.page_size = page_sizeself.start = (page - 1) * page_sizeself.end = page * page_sizeself.page_queryset = queryset[self.start:self.end]# 获取数据库中的数据条数total_count = queryset.count()# 总页数total_page_count, div = divmod(total_count, page_size)  # divmod除法函数,返回值:商,余数if div:total_page_count += 1self.total_page_count = total_page_countself.plus = plusdef html(self):# 设置按钮显示范围if self.total_page_count <= 2 * self.plus + 1:start_page = 1end_page = self.total_page_count + 1else:# 当前页小于5if self.page <= self.plus:start_page = 1end_page = 2 * self.plus + 1else:if (self.page + self.plus) > self.total_page_count:start_page = self.total_page_count - 2 * self.plusend_page = self.total_page_countelse:start_page = self.page - self.plusend_page = self.page + self.plus + 1# 页码列表page_str_list = []#获取url全部参数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):  # range前取后不取,所以还要加一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])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"><input name="page"style="position: relative;float: left;display: inline-block;width: 80px;border-radius: 0;"type="text" class="form-control" placeholder="页码"><button style="border-radius: 0" class="btn btn-default" type="submit">跳转</button></form></li>"""page_str_list.append(search_string)page_string = mark_safe("".join(page_str_list))return page_string

views.py

from django.shortcuts import render, redirect
from app01 import models
from django import forms
# 验证方式1:引入对模型的正则表达式
from django.core.validators import RegexValidator
# 验证方式2
from django.core.exceptions import ValidationError
# 后端代码安全标记到前端
from django.utils.safestring import mark_safe
#分页组件类
from app01.utils.pagination import Pagination
#------------------部门管理----------------------------------------------------------
def depart_list(request):"""部门列表"""# 1、从数据加载数据# qureyset类型=>列表[对象,对象,对象……]queryset = models.Department.objects.all()page_object = Pagination(request, queryset, page_size=5)context = {"queryset": page_object.page_queryset,"page_string": page_object.html(),}return render(request, 'depart_list.html', context)def depart_add(request):"""添加部门"""# 1、处理请求if request.method == "GET":return render(request, 'depart_add.html')# 获取用户提交的POST请求(暂时不考虑title为空的情况,后面有简单方法处理)title = request.POST.get("title")# 2、保存到数据库models.Department.objects.create(title=title)# 3、重定向回到部门列表return redirect("/depart/list/")def depart_delete(request):"""删除部门"""# 1、获取id# 通过get请求得到url的参数实现删除http://127.0.0.1:8000/depart/delete/?nid=1nid = request.GET.get("nid")# 2、删除models.Department.objects.filter(id=nid).delete()# 3、重定向回到部门列表return redirect("/depart/list/")def depart_edit(request, nid):"""部门修改"""if request.method == "GET":# 根据nid,获取想要编辑的一行对象row_object = models.Department.objects.filter(id=nid).first()# print(row_object.id,row_object.title)return render(request, 'depart_edit.html', {"row_object": row_object})# 如果用户传递过来一个post请求# 1、获取用户提交的titletitle = request.POST.get("title")# 2、根据id到数据库中的数据进行更新# models.Department.objects.filter(id=nid).update(title=title,numbers = numbers,……)models.Department.objects.filter(id=nid).update(title=title)# 3、重定向用户列表return redirect("/depart/list/")#------------------用户管理----------------------------------------------------------
def user_list(request):"""用户列表"""# 获取数据库表中的所有对象queryset = models.UserInfo.objects.all()page_object = Pagination(request,queryset,page_size=5)context = {"queryset": page_object.page_queryset,"page_string":page_object.html(),}return render(request, 'user_list.html',context)class UserModelForm(forms.ModelForm):#字段重构:编写验证规则name = forms.CharField(min_length=3,label="姓名")password = forms.CharField(min_length=6,label="密码")#validators:正则表达式,密码是6-18位数字# 重新定义ini方法def __init__(self, *args, **kwargs):# 引用父类的ini方法super().__init__(*args, **kwargs)for name, field in self.fields.items():# print(name,field)# if name == "password":# continuefield.widget.attrs = {"class": "form-control", "placeholder": field.label}class Meta:model = models.UserInfofields = ["name", "password", "age", "account", "create_time", "gender", "depart"]def user_model_add(request):"""添加用户(ModelForm)"""if request.method == "GET":# 类实例化form = UserModelForm()return render(request, 'user_model_add.html', {'form': form})#处理POST请求并校验数据form = UserModelForm(data=request.POST)if form.is_valid():#校验成功#数据合法,保存数据#{'name': '小样', 'password': '111', 'age': 11, 'account': Decimal('0'), 'create_time': datetime.datetime(2022, 10, 1, 0, 0, tzinfo=<UTC>), 'gender': 2, 'depart': <Department: 人力部>}#print(form.cleaned_data)form.save()return redirect("/user/list/")#校验失败,在页面上显示错误信息#print(form.errors)return render(request, 'user_model_add.html', {'form': form})def user_delete(request):"""删除用户"""uid = request.GET.get("uid")models.UserInfo.objects.filter(id=uid).delete()return redirect("/user/list/")def user_model_edit(request, nid):#获取当前行数据row_object = models.UserInfo.objects.filter(id=nid).first()if request.method == "GET":#将默认值传递给页面form = UserModelForm(instance=row_object)return render(request, 'user_model_edit.html',{"form":form})#处理post请求form = UserModelForm(data=request.POST,instance=row_object)# 校验if form.is_valid():form.save()return redirect("/user/list/")return render(request,'user_model_edit.html',{"form":form})#------------------靓号管理----------------------------------------------------------
class PrettyModelForm(forms.ModelForm):# 使用bootstrap样式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}# 获取模板元包class Meta:model = models.PrettyNum# 获取字段# fields = "__all__"#获取全部字段# exclude = ["level"]#反选指定字段fields = ["mobile", "price", "level", "status"]  # 获取指定字段# 验证方式2:钩子函数def clean_mobile(self):txt_mobile = self.cleaned_data["mobile"]# 验证手机号是否已存在exists = models.PrettyNum.objects.filter(mobile=txt_mobile).exists()if exists:raise ValidationError("手机号已存在")elif len(txt_mobile) != 11:raise ValidationError("手机号格式错误")return txt_mobileclass PrettyEditModelForm(forms.ModelForm):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}mobile = forms.CharField(disabled=True, label="手机号")# 验证方式1:正则表达式mobile = forms.CharField(label="手机号",validators=[RegexValidator(r'[3-9]\d{9}$', '手机号格式错误')],  # \d{11}#1[3-9]\d{9}$)class Meta:model = models.PrettyNumfields = ["mobile", "price", "level", "status"]def clean_mobile(self):# 当前编辑的那一行主键(id)# print(self.instance.pk)txt_mobile = self.cleaned_data["mobile"]# 验证手机号是否已存在(排除自身)exists = models.PrettyNum.objects.exclude(id=self.instance.pk).filter(mobile=txt_mobile).exists()if exists:raise ValidationError("手机号已存在")elif len(txt_mobile) != 11:raise ValidationError("手机号格式错误")return txt_mobiledef pretty_list(request):"""靓号列表"""# 搜索字典data_dict = {}value = request.GET.get("q", "")if value:data_dict["mobile__contains"] = value#获取查找值queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-level")# 分页组件类实例化page_object = Pagination(request,queryset)#参数字典contex = {"value": value,#数据库搜索值"qureyset": page_object.page_queryset,#分完页的数据"page_string": page_object.html(),#生成的页码}return render(request, "pretty_list.html", contex)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/")return render(request, 'pretty_add.html', {'form': form})def pretty_edit(request, nid):"""编辑靓号"""# 获取当前行数据row_object = models.PrettyNum.objects.filter(id=nid).first()if request.method == "GET":# 将默认值传递给页面form = PrettyEditModelForm(instance=row_object)return render(request, 'pretty_edit.html', {"form": form})# 处理post请求form = PrettyEditModelForm(data=request.POST, instance=row_object)# 校验if form.is_valid():form.save()return redirect("/pretty/list/")return render(request, 'pretty_edit.html', {"form": form})def pretty_delete(request):"""删除靓号"""nid = request.GET.get("nid")models.PrettyNum.objects.filter(id=nid).delete()return redirect("/pretty/list/")

urls.py

from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [#---------------------------部门管理---------------------------#部门列表path('depart/list/', views.depart_list),#部门添加path('depart/add/', views.depart_add),#部门删除path('depart/delete/', views.depart_delete),#部门修改path('depart/<int:nid>/edit/', views.depart_edit),# ---------------------------用户管理---------------------------# 用户列表path('user/list/', views.user_list),# 用户添加ModelFormpath('user/modelform/add/', views.user_model_add),# 用户删除path('user/delete/', views.user_delete),# 用户修改ModelFormpath('user/<int:nid>/edit/', views.user_model_edit),#------------------靓号管理----------------------------------------------------path('pretty/list/', views.pretty_list),path('pretty/add/', views.pretty_add),path('pretty/<int:nid>/edit/', views.pretty_edit),path('pretty/delete/', views.pretty_delete),
]

settings.py

"""
Django settings for djangoProject6 project.Generated by 'django-admin startproject' using Django 3.2.15.For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""from pathlib import Path# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-wfr)8%ew#3&qqxgif$g%48foj!g1wjxikx%ku3cqwn&jc3^u$t'# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = TrueALLOWED_HOSTS = []# Application definitionINSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','app01.apps.App01Config'
]MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]ROOT_URLCONF = 'djangoProject6.urls'TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [],'APP_DIRS': True,'OPTIONS': {'context_processors': ['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages',],},},
]WSGI_APPLICATION = 'djangoProject6.wsgi.application'# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databasesDATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'pretty_manage_system','USER': 'root','PASSWORD': '123456','HOST': '127.0.0.1','PORT': '3306',}
}# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validatorsAUTH_PASSWORD_VALIDATORS = [{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',},{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',},{'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',},{'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',},
]# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/LANGUAGE_CODE = 'zh-hans'TIME_ZONE = 'UTC'USE_I18N = TrueUSE_L10N = TrueUSE_TZ = True# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/STATIC_URL = '/static/'# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-fieldDEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
(14)Bootstrap样式父类

定义带有BootStrap样式的父类

子类继承父类的BootStrap样式

修改:
新建类文件

BootStrap.py

from django import forms
class BootStrapModelForm(forms.ModelForm):# 重新定义ini方法def __init__(self, *args, **kwargs):# 引用父类的ini方法super().__init__(*args, **kwargs)#循环ModelForm中的字段,给每个字段的插件设置for name, field in self.fields.items():#字段中有属性,保留原来属性,没有属性增加属性if field.widget.attrs:field.widget.attrs["class"] = "form-control"field.widget.attrs["placeholder"] = field.labelelse:field.widget.attrs = {"class":"form-control","placeholder":field.label}

views.py

class UserModelForm(BootStrapModelForm):#字段重构:编写验证规则name = forms.CharField(min_length=3,label="姓名",widget=forms.TextInput(attrs={"class":"form-control"}))password = forms.CharField(min_length=6,label="密码")#validators:正则表达式,密码是6-18位数字class Meta:model = models.UserInfofields = ["name", "password", "age", "account", "create_time", "gender", "depart"]class PrettyModelForm(BootStrapModelForm):# 使用bootstrap样式# 获取模板元包class Meta:model = models.PrettyNum# 获取字段# fields = "__all__"#获取全部字段# exclude = ["level"]#反选指定字段fields = ["mobile", "price", "level", "status"]  # 获取指定字段# 验证方式2:钩子函数def clean_mobile(self):txt_mobile = self.cleaned_data["mobile"]# 验证手机号是否已存在exists = models.PrettyNum.objects.filter(mobile=txt_mobile).exists()if exists:raise ValidationError("手机号已存在")elif len(txt_mobile) != 11:raise ValidationError("手机号格式错误")return txt_mobileclass PrettyEditModelForm(BootStrapModelForm):mobile = forms.CharField(disabled=True, label="手机号")# 验证方式1:正则表达式mobile = forms.CharField(label="手机号",validators=[RegexValidator(r'[3-9]\d{9}$', '手机号格式错误')],  # \d{11}#1[3-9]\d{9}$)class Meta:model = models.PrettyNumfields = ["mobile", "price", "level", "status"]def clean_mobile(self):# 当前编辑的那一行主键(id)# print(self.instance.pk)txt_mobile = self.cleaned_data["mobile"]# 验证手机号是否已存在(排除自身)exists = models.PrettyNum.objects.exclude(id=self.instance.pk).filter(mobile=txt_mobile).exists()if exists:raise ValidationError("手机号已存在")elif len(txt_mobile) != 11:raise ValidationError("手机号格式错误")return txt_mobile
(15)项目文件重构

将views.py进行功能性拆分

urls.py

from django.contrib import admin
from django.urls import path
from app01.views import depart,user,pretty
urlpatterns = [#---------------------------部门管理---------------------------#部门列表path('depart/list/', depart.depart_list),#部门添加path('depart/add/', depart.depart_add),#部门删除path('depart/delete/', depart.depart_delete),#部门修改path('depart/<int:nid>/edit/', depart.depart_edit),# ---------------------------用户管理---------------------------# 用户列表path('user/list/', user.user_list),# 用户添加ModelFormpath('user/modelform/add/', user.user_model_add),# 用户删除path('user/delete/', user.user_delete),# 用户修改ModelFormpath('user/<int:nid>/edit/', user.user_model_edit),#------------------靓号管理----------------------------------------------------path('pretty/list/', pretty.pretty_list),path('pretty/add/', pretty.pretty_add),path('pretty/<int:nid>/edit/', pretty.pretty_edit),path('pretty/delete/', pretty.pretty_delete),
]

【Django】开发日报_6_Day:手机号码管理系统-项目整合创建Bootstrap样式父类相关推荐

  1. java后台oa项目整套,[VIP源码]【S020】springboot+mybatis+bootstrap开发员工oa后台管理系统项目源码...

    java源码项目名称:springboot+mybatis+bootstrap开发员工oa后台管理系统项目源码springboot项目源码0 `" C+ a" `" ~0 ...

  2. Springboot+vue开发的图书借阅管理系统项目源码下载-P0029

    前言 图书借阅管理系统项目是基于SpringBoot+Vue技术开发而来,功能相对比较简单,分为两个角色即管理员和学生用户,核心业务功能就是图书的发布.借阅与归还,相比于一些复杂的系统,该项目具备简单 ...

  3. Django框架(2.django框架环境的搭建、项目的创建、目录文件的介绍、以及运行环境)

    Django虚拟环境和flask的虚拟环境的搭建是一样的 参考 :    https://blog.csdn.net/wei18791957243/article/details/85069310 D ...

  4. django开发的信息资产管理系统

    下载地址:https://download.csdn.net/download/asd2588258/35581031 首先展示一下登陆页: 这是首页,有个可视化图表   资产类型首页:删除.编辑.添 ...

  5. Java项目开发:学生社团管理系统

    Java项目开发:学生社团管理系统 @author:Mr.Gu @date:2021/5/31 文章目录 Java项目开发:学生社团管理系统 项目需求 开发环境 项目效果 二.项目源码 1.创建登录J ...

  6. Django开发数据可视化大屏-JS绘制大屏动态背景-(视图模板制作)

    查看本文前请先查看 Django开发数据可视化大屏-项目启动配置 通过前面的文章,我们已经创建了一个Django简单项目,并且做了相关的配置,今天我们来制作视图模板,通过JS绘制3D动态背景效果. 我 ...

  7. 【Django】开发日报_4_Day:手机号码管理系统-创建项目并实现基本功能

    目录 0.新建Django项目 (1)修改setting.py (2)删除根目录下的templates (3)创建App (4)注册App (5)创建App->templates (6)引入st ...

  8. 【Django】开发日报_3_Day:员工管理系统-创建项目

    目录 0.创建新的Django项目 1.创建app 2.注册app 3.设计表结构 4.在MySQL中生成表 5.静态文件管理 6.部门管理 6.1 部门列表 0.创建新的Django项目 step1 ...

  9. 【Django】开发日报_11_Day:手机号码管理系统-Ajax请求完善

    目录 0.Django开发回顾 如果使用sqlite3(文件数据库)可以省略很多前面的数据库配置操作 1.Ajax请求页面完善 0.Django开发回顾 如果使用sqlite3(文件数据库)可以省略很 ...

最新文章

  1. 百度搜索引擎广告SEM调用架构示意图
  2. 【知识图谱】知识融合
  3. vue生命周期大白话篇
  4. DHCP服务器的设计
  5. redhat系统双网卡绑定
  6. java 局部内部类常用么_Java中的内部类
  7. qt5 窗体显示完毕信号_iPhone手机信号不好?试试这样设置,随时随地让你的手机信号满格...
  8. WPF Bind 绑定
  9. Spark基础学习笔记08:Scala简介与安装
  10. “开源社区运营就像种菜”,黄东旭谈开源商业化 | 独家
  11. FBI 和 NSA 披露俄罗斯国家黑客使用的 Linux 恶意软件
  12. 盐城计算机考试时间安排,2019盐城中考具体时间安排 什么时候考试
  13. kali linux实现wifi扫描与密码字典破解入门
  14. 计算机键盘上的tab键是什么键,键盘Tab键有什么作用?
  15. scrapy爬虫-美图录
  16. 企业便携计算机,丢失、被盗如何远程将设备还原为出厂默认设置删除所有数据
  17. cf 1538D - Another Problem About Dividing Numbers
  18. AcWing 188. 武士风度的牛
  19. 用Processing制作小游戏1
  20. 【连载】《linux入门很简单》电子版——作者:刘金鹏(序:一切的起因2)

热门文章

  1. 学习大数据可以进入哪些高薪行业?
  2. Google可能不会显示挑逗性的网络故事
  3. android hook 多线程,从零编写Android Hook Framework
  4. 小学6年级之圆锥体积公式
  5. EAS客户端提示找不到第三方类可能的原因
  6. BZOJ 1116: [POI2008]CLO
  7. 【观察】一周之后,浪潮云ERP将直面数字化转型2.0四大攻坚战
  8. 知识点记录--x86与arm
  9. 内网计算机病毒如何查杀,如何追踪并查杀局域网ARP病毒 局域网如何查杀ARP病毒...
  10. Fortinet :《2021 年OT与网络安全现状报告》之「实践解读」