Django系列10-员工管理系统实战--靓号管理
文章目錄
- 一. 靚號(hào)管理:表結(jié)構(gòu)設(shè)計(jì)
- 二. URL調(diào)整
- 三.后端功能實(shí)現(xiàn)
- 3.1 增刪改查邏輯實(shí)現(xiàn)
- 3.2 分頁(yè)邏輯實(shí)現(xiàn)
- 四. 前端頁(yè)面
- 4.1 靚號(hào)列表
- 4.2 靚號(hào)新增
- 4.3 靚號(hào)修改
- 五. 測(cè)試
- 參考:
一. 靚號(hào)管理:表結(jié)構(gòu)設(shè)計(jì)
我們先設(shè)計(jì)一下靚號(hào)管理后臺(tái)的表結(jié)構(gòu),如下圖所示:
根據(jù)表結(jié)構(gòu)的需求,在models.py中創(chuàng)建類(lèi)(由類(lèi)生成數(shù)據(jù)庫(kù)中的表)。
class PrettyNum(models.Model):""" 靚號(hào)表 """mobile = models.CharField(verbose_name="手機(jī)號(hào)", max_length=11)# 想要允許為空 null=True, blank=Trueprice = models.IntegerField(verbose_name="價(jià)格", default=0)level_choices = ((1, "1級(jí)"),(2, "2級(jí)"),(3, "3級(jí)"),(4, "4級(jí)"),)level = models.SmallIntegerField(verbose_name="級(jí)別", choices=level_choices, default=1)status_choices = ((1, "已占用"),(2, "未使用"))status = models.SmallIntegerField(verbose_name="狀態(tài)", choices=status_choices, default=2)Django命令生成庫(kù)表
python manage.py makemigrations python manage.py migrate二. URL調(diào)整
新增對(duì)應(yīng)的 增刪改查對(duì)應(yīng)的URL,如下圖:
三.后端功能實(shí)現(xiàn)
3.1 增刪改查邏輯實(shí)現(xiàn)
主要的增刪改查的邏輯都寫(xiě)在views.py里面
views.py
# ################################# 靚號(hào)管理 ################################# from app01.utils.pagination import Pagination from django.core.validators import RegexValidator from django.core.exceptions import ValidationErrordef pretty_list(request):""" 靚號(hào)列表 """data_dict = {}search_data = request.GET.get('q', "")if search_data:data_dict["mobile__contains"] = search_dataqueryset = models.PrettyNum.objects.filter(**data_dict).order_by("-level")page_object = Pagination(request, queryset)context = {"search_data": search_data,"queryset": page_object.page_queryset, # 分完頁(yè)的數(shù)據(jù)"page_string": page_object.html() # 頁(yè)碼}return render(request, 'pretty_list.html', context)class BootStrapModelForm(forms.ModelForm):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# 循環(huán)ModelForm中的所有字段,給每個(gè)字段的插件設(shè)置for name, field in self.fields.items():# 字段中有屬性,保留原來(lái)的屬性,沒(méi)有屬性,才增加。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}class PrettyModelForm(BootStrapModelForm):# 驗(yàn)證:方式1mobile = forms.CharField(label="手機(jī)號(hào)",validators=[RegexValidator(r'^1[3-9]\d{9}$', '手機(jī)號(hào)格式錯(cuò)誤'), ],)class Meta:model = models.PrettyNum# fields = "__all__"# exclude = ['level']fields = ["mobile", 'price', 'level', 'status']# 驗(yàn)證:方式2def clean_mobile(self):txt_mobile = self.cleaned_data["mobile"]exists = models.PrettyNum.objects.filter(mobile=txt_mobile).exists()if exists:raise ValidationError("手機(jī)號(hào)已存在")# 驗(yàn)證通過(guò),用戶(hù)輸入的值返回return txt_mobileclass PrettyEditModelForm(BootStrapModelForm):# mobile = forms.CharField(disabled=True, label="手機(jī)號(hào)")mobile = forms.CharField(label="手機(jī)號(hào)",validators=[RegexValidator(r'^1[3-9]\d{9}$', '手機(jī)號(hào)格式錯(cuò)誤'), ],)class Meta:model = models.PrettyNumfields = ['mobile', 'price', 'level', 'status']# 驗(yàn)證:方式2def clean_mobile(self):# 當(dāng)前編輯的哪一行的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("手機(jī)號(hào)已存在")# 驗(yàn)證通過(guò),用戶(hù)輸入的值返回return txt_mobiledef pretty_add(request):""" 添加靚號(hào) """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):""" 編輯靚號(hào) """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})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):models.PrettyNum.objects.filter(id=nid).delete()return redirect('/pretty/list/')3.2 分頁(yè)邏輯實(shí)現(xiàn)
因?yàn)殪n號(hào)一般比較多,此時(shí)我們列表頁(yè)面需要分頁(yè)進(jìn)行展示
一般我們?cè)赼pp01目錄下增加一個(gè)utils(工具類(lèi))目錄,然后在目錄下新增一個(gè) pagination.py ,用于寫(xiě)分頁(yè)邏輯
""" 自定義的分頁(yè)組件,以后如果想要使用這個(gè)分頁(yè)組件,你需要做如下幾件事:在視圖函數(shù)中:def pretty_list(request):# 1.根據(jù)自己的情況去篩選自己的數(shù)據(jù)queryset = models.PrettyNum.objects.all()# 2.實(shí)例化分頁(yè)對(duì)象page_object = Pagination(request, queryset)context = {"queryset": page_object.page_queryset, # 分完頁(yè)的數(shù)據(jù)"page_string": page_object.html() # 生成頁(yè)碼}return render(request, 'pretty_list.html', context)在HTML頁(yè)面中{% for obj in queryset %}{{obj.xx}}{% endfor %}<ul class="pagination">{{ page_string }}</ul>"""from django.utils.safestring import mark_safeclass Pagination(object):def __init__(self, request, queryset, page_size=10, page_param="page", plus=5):""":param request: 請(qǐng)求的對(duì)象:param queryset: 符合條件的數(shù)據(jù)(根據(jù)這個(gè)數(shù)據(jù)給他進(jìn)行分頁(yè)處理):param page_size: 每頁(yè)顯示多少條數(shù)據(jù):param page_param: 在URL中傳遞的獲取分頁(yè)的參數(shù),例如:/etty/list/?page=12:param plus: 顯示當(dāng)前頁(yè)的 前或后幾頁(yè)(頁(yè)碼)"""from django.http.request import QueryDictimport copyquery_dict = copy.deepcopy(request.GET)query_dict._mutable = Trueself.query_dict = query_dictself.page_param = page_parampage = 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)if div:total_page_count += 1self.total_page_count = total_page_countself.plus = plusdef html(self):# 計(jì)算出,顯示當(dāng)前頁(yè)的前5頁(yè)、后5頁(yè)if self.total_page_count <= 2 * self.plus + 1:# 數(shù)據(jù)庫(kù)中的數(shù)據(jù)比較少,都沒(méi)有達(dá)到11頁(yè)。start_page = 1end_page = self.total_page_countelse:# 數(shù)據(jù)庫(kù)中的數(shù)據(jù)比較多 > 11頁(yè)。# 當(dāng)前頁(yè)<5時(shí)(小極值)if self.page <= self.plus:start_page = 1end_page = 2 * self.plus + 1else:# 當(dāng)前頁(yè) > 5# 當(dāng)前頁(yè)+5 > 總頁(yè)面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# 頁(yè)碼page_str_list = []self.query_dict.setlist(self.page_param, [1])page_str_list.append('<li><a href="?{}">首頁(yè)</a></li>'.format(self.query_dict.urlencode()))# 上一頁(yè)if self.page > 1:self.query_dict.setlist(self.page_param, [self.page - 1])prev = '<li><a href="?{}">上一頁(yè)</a></li>'.format(self.query_dict.urlencode())else:self.query_dict.setlist(self.page_param, [1])prev = '<li><a href="?{}">上一頁(yè)</a></li>'.format(self.query_dict.urlencode())page_str_list.append(prev)# 頁(yè)面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)# 下一頁(yè)if self.page < self.total_page_count:self.query_dict.setlist(self.page_param, [self.page + 1])prev = '<li><a href="?{}">下一頁(yè)</a></li>'.format(self.query_dict.urlencode())else:self.query_dict.setlist(self.page_param, [self.total_page_count])prev = '<li><a href="?{}">下一頁(yè)</a></li>'.format(self.query_dict.urlencode())page_str_list.append(prev)# 尾頁(yè)self.query_dict.setlist(self.page_param, [self.total_page_count])page_str_list.append('<li><a href="?{}">尾頁(yè)</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="頁(yè)碼"><button style="border-radius: 0" class="btn btn-default" type="submit">跳轉(zhuǎn)</button></form></li>"""page_str_list.append(search_string)page_string = mark_safe("".join(page_str_list))return page_string四. 前端頁(yè)面
4.1 靚號(hào)列表
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>新建靚號(hào)</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></form></div></div><div class="panel panel-default"><!-- Default panel contents --><div class="panel-heading"><span class="glyphicon glyphicon-th-list" aria-hidden="true"></span>靚號(hào)列表</div><!-- Table --><table class="table table-bordered"><thead><tr><th>ID</th><th>號(hào)碼</th><th>價(jià)格</th><th>級(jí)別</th><th>狀態(tài)</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 class="clearfix"><ul class="pagination">{{ page_string }}</ul></div></div> {% endblock %}4.2 靚號(hào)新增
pretty_add.html
{% extends 'layout.html' %}{% block content %}<div class="container"><div class="panel panel-default"><div class="panel-heading"><h3 class="panel-title"> 新建靚號(hào) </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 %}4.3 靚號(hào)修改
pretty_edit.html
{% extends 'layout.html' %}{% block content %}<div class="container"><div class="panel panel-default"><div class="panel-heading"><h3 class="panel-title"> 編輯靚號(hào) </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 %}五. 測(cè)試
簡(jiǎn)單的增刪改查此處就不再驗(yàn)證了,我們來(lái)驗(yàn)證下分頁(yè)的效果
MySQL 8.0開(kāi)始支持with語(yǔ)句遞歸,此處我們直接使用with遞歸來(lái)造測(cè)試數(shù)據(jù)
insert into app01_prettynum(mobile, price, level, status) with RECURSIVE c(n) as(select 1 union all select n + 1 from c where n < 400) select 13600000001 + n ,ceil(100*rand()),mod(n,4) + 1,mod(n,2) + 1from c;首先進(jìn)入到首頁(yè):
選擇指定頁(yè)面:
尾頁(yè)
參考:
總結(jié)
以上是生活随笔為你收集整理的Django系列10-员工管理系统实战--靓号管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: php图片检索,PHP开发入门-在线图片
- 下一篇: 数商云采购管理系统解决方案:助力企业采购