连云港网站建设培训班盘古百度推广靠谱吗
靓号界面开发
上上篇文章没有处理的问题,在这里给出解决,对用户的编辑和删除给出方法。
1、 编辑用户
-
点击编辑,跳转到编辑页面(将编辑行的ID携带过去)。
-
编辑页面(默认数据,根据ID获取并设置到页面中)
-
提交:
-
错误提示
-
数据校验
-
在数据库更新
models.UserInfo.filter(id=4).update(...)
-
def user_edit(request,nid):"""编辑用户"""row_object = models.UserInfo.objects.filter(id=nid).first()if request.method == "GET":"""设置编辑界面每一项的默认值,根据id去数据库获取要编辑的哪一行数据"""form = UserModelForm(instance=row_object)return render(request, 'user_edit.html', {'form':form})# 要指明将数据更新到nid中,否则mdelform会在list中新增一个数据form = UserModelForm( data = request.POST, instance = row_object)if form.is_valid():# 默认保存的是用户输入的所有数据,如果想要在用户输入以外增加一点值# form.instance.字段名 = 值form.save()return redirect("/user/list/")return render(request, 'user_edit.html', {'form':form})
2、删除
def user_delete(request,nid):models.UserInfo.objects.filter(id=nid).delete()return redirect("/user/list/")
一、靓号管理
1.1 表结构
根据表结构的需求,在models.py中创建类(由类生成数据库中的表)。
class PrettyNum(models.Model):""" 靓号表 """mobile = models.CharField(verbose_name="手机号", max_length=11)# 想要允许为空 null=True, blank=Trueprice = 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_choices = ((1, "已占用"),(2, "未使用"))status = models.SmallIntegerField(verbose_name="状态", choices=status_choices, default=2)
自己在数据模拟创建一些数据:
insert into app01_prettynum(mobile,price,level,status)values("111111111",19,1,1);
mysql> select * from app01_prettynum;
+----+-----------+-------+-------+--------+
| id | mobile | price | level | status |
+----+-----------+-------+-------+--------+
| 1 | 111111111 | 19 | 1 | 1 |
| 2 | 111111111 | 19 | 1 | 1 |
| 3 | 111111111 | 19 | 1 | 1 |
| 4 | 111111111 | 19 | 1 | 1 |
+----+-----------+-------+-------+--------+
4 rows in set (0.01 sec)
1.2 靓号列表
-
URL
-
函数
-
获取所有的靓号
-
结合html+render将靓号罗列出来
id 号码 价格 级别(中文) 状态(中文)
-
1.3 新建靓号
-
列表点击跳转:
/mobile/add/
-
URL
-
ModelForm类
from django import formsclass MobileModelForm(forms.ModelForm):...
class MobileModelForm(forms.ModelForm):#使用正则表达式,检验号码是否输入合法mobile = forms.CharField(label = "手机号",validators=[RegexValidator(r'^1[3-9]\d{9}$', '手机号格式错误')],)class Meta:model = models.MobileInfo##fields = ["mobile", "price", "level", "status"]fields = '__all__'# 或则排除那个字段# exclude =['lecvel']# 添加bootstrap样式def __init__(self,*args,**kwargs):super().__init__(*args,**kwargs)#循环找到所有的插件,添加class=“”样式for name, field in self.fields.items():field.widget.attrs = {'class': 'form-control', 'placeholder': field.label}## 判断手机号是否重复def clean_mobile(self):txt_mobile = self.cleaned_data['mobile'] # 获取用户提交的手机号exists = models.MobileInfo.objects.filter(mobile=txt_mobile).exists() # 正确调用 exists 方法if exists:raise ValidationError("手机号已存在") # 如果手机号已经存在,抛出验证错误return txt_mobile
-
函数
- 实例化类的对象
- 通过render将对象传入到HTML中。
- 模板的循环展示所有的字段。
-
点击提交
- 数据校验
- 保存到数据库
- 跳转回靓号列表
图片中给出两种验证手机号是否合法的方式:
- 代码解析:
mobile = forms.CharField(label="手机号", # 标签,显示在表单中,用来告诉用户这个字段代表的是手机号validators=[RegexValidator(r'^1[3-9]\d{9}$', '手机号格式错误')], # 正则验证器
)
forms.CharField
:
forms.CharField
是 Django 中用于接收字符串输入的表单字段类型。- 它通常用于接收文本数据,像是用户名、手机号等。
这里,mobile
字段的类型是 CharField
,意味着它会接收用户输入的手机号作为字符串。
label="手机号"
:
label
是表单字段的标签,表示这个字段的名称,用于向用户描述这个字段的含义。在渲染表单时,label
会显示在字段上方或旁边。- 这里的标签是
"手机号"
,表示这个字段用于输入手机号。
validators=[RegexValidator(r'^1[3-9]\d{9}$', '手机号格式错误')]
:
validators
是用于字段的验证器。它接受一个列表,其中每个元素都是一个验证函数或验证类。在这里,使用的是RegexValidator
。RegexValidator
是一个正则表达式验证器,用于根据给定的正则表达式规则验证输入值。
具体来说:
r'^1[3-9]\d{9}$'
:这是一个正则表达式,用于验证输入的手机号是否符合中国大陆的手机号格式。其含义已经在之前的回答中解释过了,验证规则是手机号以1
开头,第二位是3-9
之间的任意数字,接下来是 9 个数字。'手机号格式错误'
:这是当用户输入的手机号不符合正则表达式规则时显示的错误消息。若手机号格式不对,Django 会返回这个错误信息给用户。
正则表达式的含义
^
:表示字符串的开始。1
:手机号的第一位必须是1
。[3-9]
:手机号的第二位必须是3-9
中的任何一个数字。\d{9}
:接下来的 9 位必须是数字(\d
表示数字,{9}
表示正好 9 个数字)。$
:表示字符串的结束。
1.4 编辑靓号
- 列表页面:
/mobile/数字/edit/
- URL
- 函数
- 根据ID获取当前编辑的对象
- ModelForm配合,默认显示数据。
- 提交修改。
不允许手机号重复。
-
添加:【正则表达式】【手机号不能存在】
# [obj,obj,obj] queryset = models.PrettyNum.objects.filter(mobile="1888888888")obj = models.PrettyNum.objects.filter(mobile="1888888888").first()# True/False exists = models.PrettyNum.objects.filter(mobile="1888888888").exists()
## 判断手机号是否重复def clean_mobile(self):txt_mobile = self.cleaned_data['mobile'] # 获取用户提交的手机号exists = models.MobileInfo.objects.filter(mobile=txt_mobile).exists() # 正确调用 exists 方法if exists:raise ValidationError("手机号已存在") # 如果手机号已经存在,抛出验证错误return txt_mobile
1.5 搜索手机号
models.PrettyNum.objects.filter(mobile="19999999991",id=12)data_dict = {"mobile":"19999999991","id":123}
models.PrettyNum.objects.filter(**data_dict)
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) # 小于等于12data_dict = {"id__lte":12}
models.PrettyNum.objects.filter(**data_dict)
models.PrettyNum.objects.filter(mobile="999") # 等于
models.PrettyNum.objects.filter(mobile__startswith="1999") # 筛选出以1999开头
models.PrettyNum.objects.filter(mobile__endswith="999") # 筛选出以999结尾
models.PrettyNum.objects.filter(mobile__contains="999") # 筛选出包含999data_dict = {"mobile__contains":"999"}
models.PrettyNum.objects.filter(**data_dict)
在靓号列表函数中的如下代码便是此功能共:
data_dict = {}search_data = request.GET.get('q', "")if search_data:data_dict['mobile__contains'] = search_data
搜索框提交发出q请求,search_data接受请求,并将内容存放在data_dict中,之后在返回HTML界面显示符合条件的搜索结果
context = {'queryset': page_queryset, # 分完页的数据"search_data": search_data,"page_string": page_string # 页码}return render(request, 'mobile_list.html', context)
1.6 分页(使用公共组件)
在上一篇文章中,我们已将介绍了分页组件的使用方法:在这一我们不再重新开发:
下面是分页组件:存放在如图位置即可:
""""
自定义分页组件,之后如果想使用这个分页组件,你需要做如下的事情:
在视图函数中:
def mobile_list(request):# 1. 筛选自的情况去筛选自己的数据queryset = models.MobileInfo.objects.filter。all()# 2. 实例化分页对象page_object = Pagination(request,queryset)context = {'queryset': page_object.page_queryset, # 分完页的数据"page_string": page_object.html() # 生成所有的页码}return render(request, 'mobile_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 copyclass 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 参数中的分页参数:param plus: 当前页前后显示几页"""query_dict = copy.deepcopy(request.GET)query_dict.mutable = Trueself.query_dict = query_dictself.params = page_parampage = request.GET.get(page_param, 1)if str(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:min(self.end, len(queryset))]# 计算总页数total_count = queryset.count()self.total_page_count = (total_count + page_size - 1) // page_sizeself.plus = plus# # 总页码# total_count = queryset.count()# total_page_count, div = divmod(total_count, page_size) ## divmod返回商和余数# if div:# total_page_count += 1# self.total_page_count = total_page_count# self.plus = plusdef html(self):# 计算页码区间if self.total_page_count <= 2 * self.plus + 1:start_page = 1end_page = self.total_page_countelse:if 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# 页码生成page_str_list = []self.query_dict.setlist(self.params, [1])prev = f'<li><a href="?{self.query_dict.urlencode()}">首页</a></li>'page_str_list.append(prev)# 上一页if self.page > 1:self.query_dict.setlist(self.params, [self.page - 1])prev = f'<li><a href="?{self.query_dict.urlencode()}">上一页</a></li>'else:self.query_dict.setlist(self.params, [1])prev = f'<li><a href="?{self.query_dict.urlencode()}">上一页</a></li>'page_str_list.append(prev)# 页码for i in range(start_page, end_page + 1):self.query_dict.setlist(self.params, [i])if i == self.page:ele = f'<li class="active"><a href="?{self.query_dict.urlencode()}">{i}</a></li>'else:ele = f'<li><a href="?{self.query_dict.urlencode()}">{i}</a></li>'page_str_list.append(ele)# 下一页if self.page < self.total_page_count:self.query_dict.setlist(self.params, [self.page + 1])prev = f'<li><a href="?{self.query_dict.urlencode()}">下一页</a></li>'else:self.query_dict.setlist(self.params, [end_page])prev = f'<li><a href="?{self.query_dict.urlencode()}">下一页</a></li>'page_str_list.append(prev)# 尾页self.query_dict.setlist(self.params, [self.total_page_count])prev = f'<li><a href="?{self.query_dict.urlencode()}">尾页</a></li>'page_str_list.append(prev)page_string = mark_safe("".join(page_str_list))return page_string
""""
自定义分页组件,之后如果想使用这个分页组件,你需要做如下的事情:
在视图函数中:
def mobile_list(request):# 1. 筛选自的情况去筛选自己的数据queryset = models.MobileInfo.objects.filter。all()# 2. 实例化分页对象page_object = Pagination(request,queryset)context = {'queryset': page_object.page_queryset, # 分完页的数据"page_string": page_object.html() # 生成所有的页码}return render(request, 'mobile_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 copyclass 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 参数中的分页参数:param plus: 当前页前后显示几页"""query_dict = copy.deepcopy(request.GET)query_dict.mutable = Trueself.query_dict = query_dictself.params = page_parampage = request.GET.get(page_param, 1)if str(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:min(self.end, len(queryset))]# 计算总页数total_count = queryset.count()self.total_page_count = (total_count + page_size - 1) // page_sizeself.plus = plus# # 总页码# total_count = queryset.count()# total_page_count, div = divmod(total_count, page_size) ## divmod返回商和余数# if div:# total_page_count += 1# self.total_page_count = total_page_count# self.plus = plusdef html(self):# 计算页码区间if self.total_page_count <= 2 * self.plus + 1:start_page = 1end_page = self.total_page_countelse:if 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# 页码生成page_str_list = []self.query_dict.setlist(self.params, [1])prev = f'<li><a href="?{self.query_dict.urlencode()}">首页</a></li>'page_str_list.append(prev)# 上一页if self.page > 1:self.query_dict.setlist(self.params, [self.page - 1])prev = f'<li><a href="?{self.query_dict.urlencode()}">上一页</a></li>'else:self.query_dict.setlist(self.params, [1])prev = f'<li><a href="?{self.query_dict.urlencode()}">上一页</a></li>'page_str_list.append(prev)# 页码for i in range(start_page, end_page + 1):self.query_dict.setlist(self.params, [i])if i == self.page:ele = f'<li class="active"><a href="?{self.query_dict.urlencode()}">{i}</a></li>'else:ele = f'<li><a href="?{self.query_dict.urlencode()}">{i}</a></li>'page_str_list.append(ele)# 下一页if self.page < self.total_page_count:self.query_dict.setlist(self.params, [self.page + 1])prev = f'<li><a href="?{self.query_dict.urlencode()}">下一页</a></li>'else:self.query_dict.setlist(self.params, [end_page])prev = f'<li><a href="?{self.query_dict.urlencode()}">下一页</a></li>'page_str_list.append(prev)# 尾页self.query_dict.setlist(self.params, [self.total_page_count])prev = f'<li><a href="?{self.query_dict.urlencode()}">尾页</a></li>'page_str_list.append(prev)page_string = mark_safe("".join(page_str_list))return page_string
之后根据组件的使用方法,在靓号列表函数中使用:
## 导入自己编写的类,方便分页的代码重复编写from app01.utils.pagination import Paginationqueryset = models.MobileInfo.objects.filter(**data_dict).order_by('-level')page_object = Pagination(request,queryset)page_queryset = page_object.page_querysetpage_string = page_object.html()context = {'queryset': page_queryset, # 分完页的数据"search_data": search_data,"page_string": page_string # 页码}return render(request, 'mobile_list.html', context)
- 分页的逻辑和处理规则
- 封装分页类
- 从头到尾开发
- 写项目用【pagination.py】公共组件。