编辑用户
点击编辑,跳转到编辑页面(将编辑行的ID携带过去)
编辑页面(默认数据,根据ID获取并设置到页面中)
- urls.py
urlpatterns = [
# 用户管理
path('user/list/', views.user_list),
path('user/add/', views.user_add),
path('user/model/form/add/', views.user_model_form_add),
path('user/<int:nid>/edit', views.user_edit),
]
- views.py
def user_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_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})
- templates/user_edit.html
{% extends 'layout.html' %}
{% block content %}
<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" 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>
</div>
{% endblock %}
删除用户
- urls.py
urlpatterns = [
# 用户管理
path('user/list/', views.user_list),
path('user/add/', views.user_add),
path('user/model/form/add/', views.user_model_form_add),
path('user/<int:nid>/edit', views.user_edit),
path('user/<int:nid>/delete/', views.user_delete),
]
- views.py
def user_delete(request,nid):
# 删除部门
models.UserInfo.objects.filter(id=nid).delete()
return redirect('/user/list/')
靓号管理
数据库表结构
- models.py
class PrettyNum(models.Model):
mobile=models.CharField(verbose_name="手机号", max_length=32)
price=models.IntegerField(verbose_name="价格")
level_choices=(
(1,"1级"),
(2,"2级"),
(3,"3级"),
(4,"4级"),
)
level=models.SmallIntegerField(verbose_name="级别",choices=level_choices,default=1)
status_choice=(
(1,"已占用"),
(2,"未占用"),
)
status=models.SmallIntegerField(verbose_name="状态",choices=status_choice,default=2)
手动创建数据
insert into app01_prettynum(mobile,price,level,status) values("15000000000",190,1,1);
靓号列表
- urls.py
urlpatterns = [
#靓号管理
path('pretty/list/', views.pretty_list),
]
- views.py
def pretty_list(request):
# -level 降序
queryset=models.PrettyNum.objects.all().order_by("-level")
return render(request,"pretty_list.html",{"queryset":queryset})
- templates/pretty_list.html
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div style="margin-bottom: 10px;">
<a class="btn btn-success" href="/pretty/add/">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
新建靓号
</a>
</div>
<div class="bs-example" data-example-id="table-within-panel">
<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>
</tr>
</thead>
<tbody>
{% for obj in queryset %}
<tr>
<th>{{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 class="btn btn-primary btn-xs" href="/pretty/{{obj.id}}/edit/">编辑 </a>
<a class="btn btn-danger btn-xs" href="/pretty/{{obj.id}}/delete/">删除 </a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
新建靓号【字段校验方式new】
- urls.py
urlpatterns = [
#靓号管理
path('pretty/list/', views.pretty_list),
path('pretty/add/', views.pretty_add),
path('user/<int:nid>/edit', views.user_edit),
]
- views.py
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
class PrettyModelForm(forms.ModelForm):
# 验证方式1
# mobile = forms.CharField(
# label="手机号",
# validators=[RegexValidator(r'^1[3-9]\d{9}$','手机号格式错误1')],
# )
# 验证方式2
def clean_mobile(self):
txt_mobile = self.cleaned_data["mobile"]
exists=models.PrettyNum.objects.exclude(id=self.instance.pk).filter(mobile=txt_mobile).exists()
if exists:
raise ValidationError("手机号已存在")
if len(txt_mobile) != 11:
raise ValidationError("手机号格式错误2")
#验证通过,返回用户输入
return txt_mobile
class Meta:
model=models.PrettyNum
# fields=["mobile","price","level","status"] # 自定义字段
fields="__all__" # 所有字段
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
# 给所有字段的input框加上class:"form-control"
for name,field in self.fields.items():
# if name=="password":
# continue
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})
form = PrettyModelForm(data=request.POST)
if form.is_valid():
form.save() # 自动存储到数据库中
return redirect("/pretty/list/")
else:
return render(request,'pretty_add.html',{"form":form})
- templates/pretty_add.html
{% extends 'layout.html' %}
{% block content %}
<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" 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>
</div>
{% endblock %}
编辑靓号
- urls.py
urlpatterns = [
#靓号管理
path('pretty/list/', views.pretty_list),
path('pretty/add/', views.pretty_add),
path('pretty/<int:nid>/edit/', views.pretty_edit),
]
- views.py
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})
- templates/pretty_edit.html
{% extends 'layout.html' %}
{% block content %}
<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" 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>
</div>
{% endblock %}
删除靓号
- urls.py
urlpatterns = [
#靓号管理
path('pretty/list/', views.pretty_list),
path('pretty/add/', views.pretty_add),
path('pretty/<int:nid>/edit/', views.pretty_edit),
path('pretty/<int:nid>/delete/', views.pretty_delete),
]
- views.py
def pretty_delete(request):
nid = request.GET.get("nid")
models.PrettyNum.objects.filter(id=nid).delete()
return redirect('/pretty/list/')
靓号搜索
Django查询条件
#比较大小
models.PrettyNum.objects.filter(id=12) #等于12
models.PrettyNum.objects.filter(id__gt=12) #大于12
models.PrettyNum.objects.filter(id__gte=12) #大于等于12
models.PrettyNum.objects.filter(id__lt=12) #小于12
models.PrettyNum.objects.filter(id__lte=12) #小于等于12
#筛选字符串
models.PrettyNum.objects.filter(mobile="150") #150开头
models.PrettyNum.objects.filter(mobile__startwith="150") #150开头
models.PrettyNum.objects.filter(mobile__endwith="150") #150结尾
models.PrettyNum.objects.filter(mobile__contains="150") #包含150
#使用字典传条件
data_dict={"id__ite":12}
models.PrettyNum.objects.filter(**data_dict)
- views.py
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")
return render(request,"pretty_list.html",{"queryset":queryset,"search_data":search_data})
- templates/pretty_list.html
<div style="margin-bottom: 10px;" class="clearfix">
<a class="btn btn-success" href="/pretty/add/">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
新建靓号
</a>
<div style="float:right; width:300px;">
<form method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search for..." value="{{search_data}}">
<span class="input-group-btn">
<button class="btn btn-default" type="submit"><span class="glyphicon glyphicon-search"
aria-hidden="true"></span></button>
</span>
</div><!-- /input-group -->
</form>
</div>
</div>
靓号分页
创建靓号300个
for i in range(300):
models.PrettyNum.objects.create(mobile="12345678901",price=10,level=1,status=1)
数据库取前十条
queryset=models.PrettyNum.objects.all()[0:10]
分页逻辑
- views.py
def pretty_list(request):
data_dict = {}
search_data = request.GET.get("q", "")
if search_data:
data_dict["mobile__contains"] = search_data
page = int(request.GET.get("page", 1))
page_size = 10 # 每页10个数据
start = (page-1)*page_size
end = page*page_size
queryset = models.PrettyNum.objects.filter(
**data_dict).order_by("-level")[start:end]
# 数据总条数
total_count = models.PrettyNum.objects.filter(**data_dict).count()
total_page_count, div = divmod(total_count, page_size)
if div:
total_page_count += 1
# 页码,
plus = 5
# 数据库数据没达到11页时
if total_page_count <= 2*plus+1:
start_page = 1
end_page = total_page_count
# 数据多,根据当前页的前后五页
else:
if page <= plus:
start_page = 1
end_page = 2 * plus+1
elif page+plus >= total_page_count:
start_page = total_page_count-2*plus
end_page = total_page_count
else:
start_page = page-plus
end_page = page+plus
# 拼接html
page_str_list = []
# 上一页
if page > 1:
prev = '<li><a href="?page={}">上一页</a></li>'.format(page-1)
else:
prev = '<li><a href="?page={}">上一页</a></li>'.format(1)
page_str_list.append(prev)
# 页码
for i in range(start_page, end_page+1):
if i == page:
ele = '<li class="active"><a href="?page={}">{}</a></li>'.format(
i, i)
else:
ele = '<li><a href="?page={}">{}</a></li>'.format(i, i)
page_str_list.append(ele)
# 下一页
if page < total_page_count:
next = '<li><a href="?page={}">下一页</a></li>'.format(page+1)
else:
next = '<li><a href="?page={}">下一页</a></li>'.format(total_page_count)
page_str_list.append(next)
search_string='''
<li>
<form method="get" style="float:left;margin-left: -1px;">
<input type="text" style="position:relative; float: left;width:80px; border-radius:0; display: inline-block;"
name="page" 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 render(request, "pretty_list.html", {"queryset": queryset, "search_data": search_data, "page_string": page_string})
- templates/pretty_list.html
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div style="margin-bottom: 10px;" class="clearfix">
<a class="btn btn-success" href="/pretty/add/">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
新建靓号
</a>
<div style="float:right; width:300px;">
<form method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search for..." value="{{search_data}}">
<span class="input-group-btn">
<button class="btn btn-default" type="submit"><span class="glyphicon glyphicon-search"
aria-hidden="true"></span></button>
</span>
</div><!-- /input-group -->
</form>
</div>
</div>
<div class="bs-example" data-example-id="table-within-panel">
<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>
</tr>
</thead>
<tbody>
{% for obj in queryset %}
<tr>
<th>{{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 class="btn btn-primary btn-xs" href="/pretty/{{obj.id}}/edit/">编辑 </a>
<a class="btn btn-danger btn-xs" href="/pretty/{{obj.id}}/delete/">删除 </a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<ul class="pagination" style="float: left;">
{{page_string}}
</ul>
</div>
</div>
{% endblock %}
封装分页组件
分页类重写靓号列表
- utils/pagination.py
"""
自定义分页组件,以后要使用该分页组件,需要做以下几件事:
在视图函数中:
def pretty_list(request):
# 1、根据自己情况筛选数据
queryset = models.PrettyNum.objects.all()
# 2、实例化分页对象
page_object = Pagination(request,queryset)
context= {
"queryset": page_object.page_queryset, # 分完页的数据
"page_string": page_object.html() # 页码html
}
return render(request, "pretty_list.html",context)
在html中:
{% for obj in queryset %}
{{obj.id}}
{% endfor %}
<ul class="pagination">
{{page_string}}
</ul>
"""
from django.utils.safestring import mark_safe
import copy
class Pagination(object):
'''
description:
param {*} request:请求对象
param {*} queryset:查询符合条件的数据,根据这个数据进行分页处理
param {*} page_size:每页显示多少条数据
param {*} page_param:在URL中传递的获取分页的参数,例如:pretty/list/?page=1
param {*} plus:显示当前页的前几页或后几页
'''
def __init__(self, request,queryset, page_size=10, page_param="page",plus=5):
query_dict=copy.deepcopy(request.GET)
query_dict._mutable=True
self.query_dict=query_dict
self.page_param=page_param
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.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):
# 页码,
self.plus = 5
# 数据库数据没达到11页时
if self.total_page_count <= 2*self.plus+1:
start_page = 1
end_page = self.total_page_count
# 数据多,根据当前页的前后五页
else:
if self.page <= self.plus:
start_page = 1
end_page = 2 * self.plus+1
elif 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
# 拼接html
page_str_list = []
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+1):
if i == self.page:
self.query_dict.setlist(self.page_param,[i])
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])
page_str_list.append('<li><a href="?{}">尾页</a></li>'.format(self.query_dict.urlencode()))
search_string='''
<li>
<form method="get" style="float:left;margin-left: -1px;">
<input type="text" style="position:relative; float: left;width:80px; border-radius:0; display: inline-block;"
name="page" 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 app01.utils.pagination import Pagination
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= {
"search_data": search_data,
"queryset": page_object.page_queryset, # 分完页的数据
"page_string": page_object.html() # 页码html
}
return render(request, "pretty_list.html",context)
分页类重写用户列表
- views.py
def user_list(request):
queryset = models.UserInfo.objects.all()
page_object = Pagination(request, queryset,page_size=2)
context={
"queryset":page_object.page_queryset,
"page_string":page_object.html()
}
return render(request, 'user_list.html',context)
templates/user_list.html
</table>
</div>
<div class="clearfix">
<ul class="pagination">
{{page_string}}
</ul>
</div>
Bootstrap样式父类
ModelForm可以帮助我们生成HTML标签
class UserModelForm(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = ["name", "password", "age", "create_time", "gender", "depart"]
form=UserModelForm()
但他是普通input框
{{form.name}} # 普通的input框
{{form.password}} # 普通的input框
可以使用插件给input框定义样式
class UserModelForm(forms.ModelForm):
name = forms.CharField(min_length=3, label="用户名")
class Meta:
model = models.UserInfo
fields = ["name", "password", "age"]
widgets={
"name":
"password":forms.PasswordInput(attrs={"class":"form-control"})
}
form=UserModelForm()
class UserModelForm(forms.ModelForm):
name = forms.CharField(
min_length=3,
label="用户名",
widget=forms.TextInput(attrs={"class":"form-control"})
)
class Meta:
model = models.UserInfo
fields = ["name", "password", "age"]
重新定义init方法,批量设置样式
class UserModelForm(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = ["name", "password", "age"]
def __init__(self, *args, **kwargs):
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.label
else:
field.widget.attrs = {
"class": "form-control",
"placeholder": field.label
}
自定义类BootStrapModelForm
直接继承BootStrapModelForm,而不是forms.ModelForm
from django import forms
class BootstrapModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
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.label
else:
field.widget.attrs = {
"class": "form-control",
"placeholder": field.label
}
创建utils/form.py存放Form类
from app01 import models
from django import forms
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from app01.utils.bootstrap import BootstrapModelForm
class UserModelForm(BootstrapModelForm):
# 验证规则
name = forms.CharField(
min_length=3,
label="用户名",
widget=forms.TextInput(attrs={"class":"form-control"})
)
class Meta:
model = models.UserInfo
fields = ["name", "password", "age", "create_time", "gender", "depart"]
class PrettyModelForm(BootstrapModelForm):
# 验证方式1
# mobile = forms.CharField(
# label="手机号",
# validators=[RegexValidator(r'^1[3-9]\d{9}$','手机号格式错误1')],
# )
# 验证方式2
def clean_mobile(self):
txt_mobile = self.cleaned_data["mobile"]
exists = models.PrettyNum.objects.exclude(
id=self.instance.pk).filter(mobile=txt_mobile).exists()
if exists:
raise ValidationError("手机号已存在")
if len(txt_mobile) != 11:
raise ValidationError("手机号格式错误2")
# 验证通过,返回用户输入
return txt_mobile
class Meta:
model = models.PrettyNum
# fields=["mobile","price","level","status"] # 自定义字段
fields = "__all__" # 所有字段
class PrettyEditModelForm(BootstrapModelForm):
mobile = forms.CharField(
label="手机号",
validators=[RegexValidator(r'^1[3-9]\d{9}$','手机号格式错误1')],
)
class Meta:
model = models.PrettyNum
fields=["mobile","price","level","status"] # 自定义字段
删除views.py
创建views文件夹,将不同业务的视图函数放到不同.py文件中
app01/views
-depart.py
-user.py
-pretty.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),
# <int:nid>正则表达式
path('depart/<int:nid>/edit/', depart.depart_edit),
# 用户管理
path('user/list/', user.user_list),
path('user/add/', user.user_add),
path('user/model/form/add/', user.user_model_form_add),
path('user/<int:nid>/edit', user.user_edit),
path('user/<int:nid>/delete/', user.user_delete),
#靓号管理
path('pretty/list/', pretty.pretty_list),
path('pretty/add/', pretty.pretty_add),
path('pretty/<int:nid>/edit/', pretty.pretty_edit),
path('pretty/<int:nid>/delete/', pretty.pretty_delete),
]
版权归原作者 麟麟菜菜子 所有, 如有侵权,请联系我们删除。