提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
1.在models.py下
class Department(models.Model):
"""部门表"""
title =models.CharField(verbose_name="标题",max_length=32)
def __str__(self):
return self.title
2.在views文件下
def …(request):return(request,’…html’)
def depart_list(request):
"""部门类"""
# 去数据库中获取所有的部门列表
queryset = models.Department.objects.all()
return render(request, 'depart_list.html', queryset )
3.depart_list.html文件下
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div class="panel panel-default" style="margin-top: 20px;">
<div class="panel-heading">
<span class="glyphicon glyphicon-th-list" aria-hidden="true">span>
批量上传
div>
<div class="panel-body">
<form method="post" enctype="multipart/form-data" action="/depart/multi/">
{% csrf_token %}
<div class="form-group">
<input type="file" name="exc">
div>
<input type="submit" value="上传" class="btn btn-info btn-sm">
form>
div>
<div style="margin-bottom: 10px">div>
<div class="panel-heading">
<a class="btn btn-success btn-xs " href="/depart/add/">
<span class="glyphicon glyphicon-plus" aria-hidden="true">span>
新建部门
a>
div>
<table class="table">
<thead>
<tr>
<th>idth>
<th>名称th>
<th>操作th>
tr>
thead>
<tbody>
{% for obj in queryset %}
<tr>
<th scope="row">{{ obj.id }}th>
<td>{{ obj.title }}td>
<td>
<a href="/depart/{{ obj.id }}/edit/" class="btn btn-primary btn-xs ">编辑a>
<a href="/depart/delete/?nid={{ obj.id }}" class="btn btn-danger btn-xs ">删除a>
td>
tr>
{% endfor %}
tbody>
table>
div>
div>
{% endblock %}
注意:两个html文件中都需要{% load static %}
添加部门
1)在urls.py下创建path(‘depart/add/’, views.depart_add),
2)在views.py下创建def depart_add(request)
def depart_add(request):
"""添加部门"""
if request.method == 'GET':
return render(request, 'depart_add.html')
# 获取用户POST提交过来的数据
title = request.POST.get("title")
# 保存到数据库
models.Department.objects.create(title=title)
# 重定向部门列表
return redirect("/depart/list/")
3)templates目录下创建depart_add.html
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">新建部门div>
<div class="panel-body">
<form class="form-horizontal" method="post">
{% csrf_token %}
<div class="form-group">
<label class="col-sm-2 control-label">标题label>
<div class="col-sm-10">
<input type="text" class="form-control" placeholder="标题" name="title"/>
div>
div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">提 交button>
div>
div>
form>
div>
div>
div>
{% endblock %}
4)在depart_list.html文件下新建部门处链接到depart/add/地址
删除部门
1)在urls.py下创建path(‘depart/delete/’, views.depart_delete),
2)在views.py下创建def depart_delete(request,nid)
def depart_delete(request, nid):
"""删除部门"""
# 获取id
nid = request.GET.get('nid')
# 删除
models.Department.objects.filter(id=nid).delete()
# 跳转(重定向回部门列表)
return redirect("/depart/list/")
3)在depart_list.html文件下的删除按钮内
<a href="/depart/delete/?nid={{ obj.id }}" class="btn btn-danger btn-xs ">删除a>
编辑部门
1)在urls.py下创建path(‘depart/edit/’, views.depart_edit),
http://127.0.0.1:8000/depart/int/edit/
path('depart//edit/' , views.depart_edit),
2)在views.py下创建def depart_edit(request,nid)
def depart_edit(request, nid):
"""编辑部门"""
if request.method == "GET":
# 根据id获取编辑的数据
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})
# 用户提交的标题
title = request.POST.get("title")
# 根据id在数据库中进行更新
models.Department.objects.filter(id=nid).update(title=title)
# 跳转(重定向回部门列表)
return redirect("/depart/list/")
3)vaule表示默认值,在depart_list.html文件下的编辑按钮内
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">修改部门div>
<div class="panel-body">
<form class="form-horizontal" method="post">
{% csrf_token %}
<div class="form-group">
<label class="col-sm-2 control-label">标题label>
<div class="col-sm-10">
<input type="text" class="form-control" placeholder="标题" name="title" value="{{ row_object.title }}"/>
div>
div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">提 交button>
div>
div>
form>
div>
div>
div>
{% endblock %}
获取数据
insert into app01_userinfo(name,password,age,account,creat_time,gender,depart_id) values("刘乐","1e4q",42,3321.02,"2010-03-11",2,11);
在models.py文件下
class UserInfo(models.Model):
"""员工表"""
name =models.CharField(verbose_name="姓名",max_length=32)
password =models.CharField(verbose_name="密码",max_length=32)
age =models.IntegerField(verbose_name="年龄")
account =models.DecimalField(verbose_name="余额",max_digits=10,decimal_places=2,default=0)
creat_time =models.DateField(verbose_name="入职时间")
# 有约束 on_delete=models.CASCADE级联删除
depart = models.ForeignKey(verbose_name="所属部门",to="Department",to_field="id",on_delete=models.CASCADE)
# 链接部分被删除时置空
# depart = models.ForeignKey(to="Department",to_field="id",null=True,blank=True,on_delete=models.SET_NULL)
# 在django中做的约束
gender_choices=(
(1,"男"),
(2,"女"),
)
gender =models.SmallIntegerField(verbose_name="性别",choices=gender_choices)
在user_list.html文件下
"""注意:return render(request,"user_list.html", {"queryset": queryset})(双引号、花括号、冒号)"""
<th>{{ obj.id }}th>
<td>{{ obj.name }}td>
<td>{{ obj.password }}td>
<td>{{ obj.age }}td>
<td>{{ obj.account }}td>
<td>{{ obj.creat_time|date:"Y-m-d" }}td>#日期的读取
<td>{{ obj.get_gender_display }}td>#性别
<td>{{ obj.depart.title }}td> #关联其他表的读取
在没有利用Django组件:ModelForm组件下
添加用户
def user_add(request):
if request.method == "GET":
context = {
'gender_choices': models.UserInfo.gender_choices,
'depart_list': models.Department.objects.all()
}
return render(request, "user_add.html", context)
name = request.POST.get("name")
password = request.POST.get("password")
age = request.POST.get("age")
account = request.POST.get("account")
# from django.utils import timezone
# creat_time = timezone.now()
creat_time = request.POST.get("creat_time")
gender = request.POST.get("gender")
depart_id = request.POST.get("depart_id")
models.UserInfo.objects.create(name=name, password=password, age=age,
account=account, creat_time=creat_time,
gender=gender, depart_id=depart_id)
return redirect("/user/list/")
利用Django组件:ModelForm组件
在views.py文件下
class UserModelForm(forms.ModelForm):
# name = forms.CharField(min_length=3, label="用户名")
class Meta:
model = models.UserInfo
fields = ["name", "password", "age", "account", "creat_time", "gender", "depart"]
# widgets = {
# "name":forms.TextInput(attrs={"class":"col-sm-2 control-label"})
# }
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环找到所有的插件,添加了"class":"form-control"得样式
for name, field in self.fields.items():
print(name, field)
field.widget.attrs = {"class": "form-control", "placeholder": field.label}
添加用户
GET下:form = UserModelForm()
POST下:form = UserModelForm(data=request.POST)
from django import forms
def use_model_form_add(request):
"""添加用户"""
if request.method == "GET":
form = UserModelForm()
return render(request, 'user_model_form_add.html', {"form": form})
# 用户提交的数据进行校验,如果合法再保存到数据库
form = UserModelForm(data=request.POST)
if form.is_valid():
# print(form.cleaned_data)
form.save()
return render(request, 'user_model_form_add.html', {"form": form})
"编辑用户
GET下:form = UserModelForm(instance=row_object)
POST下:form = UserModelForm(data=request.POST, instance=row_object)
from django import forms
def user_edit(request, nid):
"""编辑用户"""
# 根据id去数据库获取要编辑的那一行数据
row_object = models.UserInfo.objects.filter(id=nid).first()
if request.method == "GET":
# instance=row_object表示将数据库中获取的那行的每一个值都显示在页面上
form = UserModelForm(instance=row_object)
return render(request, 'use_edit.html', {"form": form})
form = UserModelForm(data=request.POST, instance=row_object)
if form.is_valid():
form.save()
return redirect('/user/list')
return render(request, 'user_edit.html', {"form": form})
删除用户
def user_delete(request, nid):
"""删除用户"""
models.UserInfo.objects.filter(id=nid).delete()
return redirect('/user/list/')
首先在models.py文件下定义PrettyNum这个类,同时用djando命令生成数据库表(python manage.py makemigrations;python manage.py migrate)数据库下才有app01_prettynum这个数据表
views.py文件下
from django import forms
from django.core.validators import RegexValidator
class PrettyModelForm(forms.ModelForm):
# 验证:方法1
mobile = forms.CharField(
label="手机号",
# validators=[RegexValidator(r'^159[0-9]+$','数字必须以159开头')],
validators=[RegexValidator(r'^1[3-9]\d{9}$', '手机号格式错误')],
)
class Meta:
model = models.PrettyNum
# fields = ['mobiles','price','level','status'] 一一列举
# exclude = ['level'] 排除
fields = "__all__"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环找到所有的插件,添加了"class":"form-control"得样式
for name, field in self.fields.items():
print(name, field)
field.widget.attrs = {"class": "form-control", "placeholder": field.label}
添加靓号
def pretty_add(request):
if request.method == 'GET':
form = PrettyModelForm()
return render(request, 'pretty_add.html', {"form": form})
row_object = models.PrettyNum.objects.create()
form = PrettyModelForm(data=request.POST, instance=row_object)
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 = PrettyModelForm(instance=row_object)
return render(request, 'pretty_edit.html', {"form": form})
form = PrettyModelForm(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):
models.PrettyNum.objects.filter(id=nid).delete()
return redirect('/pretty/list/')
靓号列表
def pretty_list(request):
data_dict = {}
search_data = request.GET.get('q', "")
if search_data:
data_dict["mobile__contains"] = search_data
queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-level")
page_object = Pagination(request, queryset) # 分页
context = {
"queryset": page_object.page_queryset,
"search_data": search_data, # 分完页的数据
"page_string": page_object.html() # 页码
}
return render(request, 'pretty_list.html', context)
搜索靓号
对于数字类型:
filter(id=12) #等于12
filter(id__gt=12) #大于12
filter(id__gte=12) #大于等于12
filter(id__lt=12) #小于12
filter(id__lte=12) #小于等于12
filter(id=12)
对于字符串类型:
filter(mobile=”1999”)
filter(mobile__startswith=”1999”) #筛选1999开头
filter(mobile__endswith=”1999”)
filter(mobile__contains=”1999”)
4.分页组件的创建
在appo01目录下创建utils目录,并创建pagination.py文件
"""
自定义分页组件
"""
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=4
:param plus:显示当前页的前或后几页(页码)
"""
import copy
query_dict = copy.deepcopy(request.GET)
query_dict._mutable = True
self.query_dict = query_dict
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.page_param=page_param
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
else:
# 数据较多
# 当前页<5
if self.page <= self.plus:
start_page = 1
end_page = 2 * self.plus + 1
else:
# 当前页>5
# 当前页+5>总页面
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
# 页码
page_str_list = []
self.query_dict.setlist(self.page_param,[1])
first = '<li><a href="?{}">首页a>li>'.format(self.query_dict.urlencode())
page_str_list.append(first)
# 上一页
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:
prev = '<li><a href="?{}">《a>li>'.format(1)
page_str_list.append(prev)
for i in range(start_page, end_page + 1):
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])
next = '<li><a href="?{}">》a>li>'.format(self.query_dict.urlencode())
else:
self.query_dict.setlist(self.page_param,[self.total_page_count])
next = '<li><a href="?{}">》a>li>'.format(self.query_dict.urlencode())
page_str_list.append(next)
# 尾页
self.query_dict.setlist(self.page_param,[self.total_page_count])
end = '<li><a href="?{}">尾页a>li>'.format(self.query_dict.urlencode())
page_str_list.append(end)
search_string = """
<li >
<form method="get" style="float: left">
<input type="text"
class="form-control" name="page" placeholder="页码"
style="width: 80px;position: relative;float: left;display: inline-block;border-radius: 0">
<button type="submit" class="btn btn-default">跳转button>
form>
li>
"""
page_str_list.append(search_string)
page_string = mark_safe("".join(page_str_list))
return page_string
注意:
"""如果以后想要使用这个分页组件,你需要做如下几件事:
在视图函数views.py函数中:
def pretty_list(request):
#1.根据所需筛选数据
queryset = models.PrettyNum.objects.all()
#2.实例化分页对象
page_object = Pagination(request,queryset,page_size=2)
context ={
"queryset": page_object.page_queryset, #分完页的数据
"page_string": page_object.html() #生成页码
}
return render(request, 'pretty_list.html',context)
在html页面中
<ul class="pagination">
{{ page_string }}
ul>
"""
靓号列表(pretty_list)
views.py文件如上,需要提前导入:
from app01.utils.pagination import Pagination
pretty_list.html文件
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div class="panel panel-default" >
<div class="panel-heading" >
<a class="btn btn-success btn-xs " href="/pretty/add/">
<span class="glyphicon glyphicon-plus" aria-hidden="true">span>
添加靓号
a>
<div class="col-lg-3" style="float: right;display: block;padding-bottom: 5px">
<form method="get">
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">
<span class="glyphicon glyphicon-zoom-in" aria-hidden="true">span>
button>
span>
<input type="text"name='q' class="form-control" placeholder="Search for..."
value="{{ search_data }}">
div>
form>
div>
div>
<table class="table">
<thead>
<tr>
<th>idth>
<th>电话号th>
<th>单价th>
<th>级别th>
<th>状态th>
<th>操作th>
tr>
thead>
<tbody>
{% for obj in queryset %}
<tr>
<th scope="row">{{ 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 href="/pretty/{{ obj.id }}/edit/" class="btn btn-primary btn-xs ">编辑a>
<a href="/pretty/{{ obj.id }}/delete/" class="btn btn-danger btn-xs ">删除a>
td>
tr>
{% endfor %}
tbody>
table>
div>
<div>
<nav>
<ul class="pagination">
{{ page_string }}
ul>
nav>
div>
div>
{% endblock %}
在appo01目录下创建utils目录,并创建bootstrap.py文件
from django import forms
class BootstrapModelForm(forms.ModelForm):
bootstrap_exclude_fields = ['img']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环找到所有的插件,添加了"class":"form-control"得样式
for name, field in self.fields.items():
if name in self.bootstrap_exclude_fields:
continue
# 字段中有属性,保留原来的属性,没有属性,才增加
if field.widget.attrs:
# 有则添加字典值
field.widget.attrs["class"] = "form-control"
field.widget.attrs["placeholder"] = field.label
else:
field.widget.attrs = {
"class": "form-control",
"placeholder": field.label
}
与没有Bootstrap样式的ModelForm的区别,在于需要提前引用
from app01.utils.bootstrap import BootstrapModelForm
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