1. 创建手机号表
| |
| |
| from django.db import models |
| class Phone(models.Model): |
| """用户手机号""" |
| phone = models.CharField(verbose_name="手机号", max_length=64) |
| |
| number = models.IntegerField(verbose_name="登陆次数", default=0) |
| |
| level_choices = ( |
| (1, "用户"), |
| (2, "超级管理员") |
| ) |
| level = models.SmallIntegerField(verbose_name="类别", choices=level_choices, default=1) |
| |
| status_choices = ( |
| (1, "正常"), |
| (2, "异常") |
| ) |
| status = models.SmallIntegerField(verbose_name="状态", choices=status_choices, default=1) |
| |
| |
| |
| |
2. 创建路由(url)
| |
| |
| from bbc_list.views import login, home_page, order, phone |
| urlpatterns = [ |
| path("phone/list/", phone.phone_list), |
| path("phone/add/", phone.phone_add), |
| path("phone/<int:nid>/update/", phone.phone_update), |
| path("phone/<int:nid>/delete/", phone.phone_delete),] |
| |
| |
| |
| from django import forms |
| from bbc_list import models |
| from bbc_list.utils.bootstrap import BootStrapModelForm |
| |
| class PhoneModelForm(BootStrapModelForm): |
| """新增""" |
| |
| from django.core.validators import RegexValidator |
| phone = forms.CharField(label="手机号", |
| validators=[RegexValidator(r'1[3-9]\d{9}$', '手机号格式错误'), ], |
| ) |
| |
| |
| class Meta: |
| model = models.Phone |
| fields = ['phone', 'number', 'level', 'status'] |
| |
| |
| |
| |
| def clean_phone(self): |
| from django.core.validators import ValidationError |
| txt = self.cleaned_data["phone"] |
| exists = models.Phone.objects.filter(phone=txt).exists() |
| |
| |
| if exists: |
| raise ValidationError("手机号已存在") |
| |
| |
| return txt |
| |
| |
| class PhoneUpdateModelForm(BootStrapModelForm): |
| """修改""" |
| |
| |
| from django.core.validators import RegexValidator |
| phone = forms.CharField( |
| label="手机号", |
| validators=[RegexValidator(r'1[3-9]\d{9}$', "手机号格式错误")] |
| ) |
| |
| class Meta: |
| model = models.Phone |
| fields = ['phone', 'number', 'level', 'status'] |
| |
| |
| def clean_phone(self): |
| from django.core.validators import ValidationError |
| |
| |
| print("instance.pk==", self.instance.pk) |
| |
| txt = self.cleaned_data["phone"] |
| exists = models.Phone.objects.exclude(id=self.instance.pk).filter(phone=txt).exists() |
| |
| if exists: |
| raise ValidationError("手机号已存在") |
| |
| |
| return txt |
| |
4. 编写视图函数
| |
| |
| from django.shortcuts import render, redirect |
| |
| from bbc_list import models |
| from bbc_list.utils.form import PhoneModelForm, PhoneUpdateModelForm |
| |
| |
| def phone_list(request): |
| """手机号列表""" |
| |
| data_dict = {} |
| search_data = request.GET.get("q", "") |
| |
| if search_data: |
| data_dict["phone__contains"] = search_data |
| |
| |
| from bbc_list.utils.pagemtion import Pagination |
| |
| queryset = models.Phone.objects.filter(**data_dict).order_by("-level") |
| |
| page_object = Pagination(request, queryset) |
| context = { |
| "search_data": search_data, |
| |
| "phone": page_object.page_queryset, |
| "page_string": page_object.html() |
| |
| } |
| |
| return render(request, "phone_list.html", context) |
| |
| |
| def phone_add(request): |
| """添加手机号""" |
| if request.method == "GET": |
| form = PhoneModelForm() |
| |
| return render(request, "phone_add.html", {"form": form}) |
| |
| form = PhoneModelForm(data=request.POST) |
| if form.is_valid(): |
| form.save() |
| return redirect("/phone/list/") |
| |
| return render(request, "phone_add.html", {"form": form}) |
| |
| |
| def phone_update(request, nid): |
| """修改手机号""" |
| row_object = models.Phone.objects.filter(id=nid).first() |
| if request.method == "GET": |
| form = PhoneUpdateModelForm(instance=row_object) |
| return render(request, "phone_update.html", {"form": form}) |
| |
| form = PhoneUpdateModelForm(data=request.POST, instance=row_object) |
| |
| if form.is_valid(): |
| form.save() |
| return redirect("/phone/list/") |
| |
| return render(request, "phone_update.html", {"form": form}) |
| |
| |
| def phone_delete(request, nid): |
| """删除手机号""" |
| models.Phone.objects.filter(id=nid).delete() |
| return redirect("/phone/list/") |
| |
| |
5. 编写html页面
| # phone_list.html |
| |
| {% extends 'one.html' %} |
| |
| {% block content %} |
| <div class="container"> |
| <div style="margin-bottom:10px;" class="clearfix"> |
| <a class="btn btn-success" href="/phone/add/"> |
| <span class="glyphicon glyphicon-plus" aria-hidden="true"> |
| 新建手机号</span></a> |
| |
| <div style="float:right;width:300px;"> |
| <form method="post"> |
| {% csrf_token %} |
| <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> |
| |
| <a class="btn btn-success" href="/phone/add/"> |
| <span class="glyphicon glyphicon-plus" aria-hidden="true"> |
| 新建手机号ModelForm</span></a> |
| </div> |
| <div class="panel panel-default"> |
| <div class="panel-heading"> |
| <span class="glyphicon glyphicon-th-list" aria-hidden="true"> |
| 手机号列表 |
| </span> |
| </div> |
| |
| <table class="table table-bordered"> |
| <thead> |
| <tr> |
| <th>ID</th> |
| <th>手机号</th> |
| <th>登陆次数</th> |
| <th>类别</th> |
| <th>状态</th> |
| </tr> |
| </thead> |
| <tbody> |
| {% for obj in phone %} |
| <tr> |
| <th>{{ obj.id }}</th> |
| <th>{{ obj.phone }}</th> |
| <th>{{ obj.number }}</th> |
| |
| <td>{{ obj.get_level_display }}</td> |
| <td>{{ obj.get_status_display }}</td> |
| <td> |
| <a class="btn btn-primary btn-xs" href="/phone/{{ obj.id }}/update/">编辑</a> |
| <a class="btn btn-danger btn-xs" href="/phone/{{ obj.id }}/delete/">删除</a> |
| </td> |
| </tr> |
| {% endfor %} |
| </tbody> |
| </table> |
| </div> |
| <div class="clearfix"> |
| <ul class="pagination"> |
| {{ page_string }} |
| </ul> |
| </div> |
| |
| </div> |
| |
| |
| {% endblock %} |
| # phone_add.html |
| {% extends 'one.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 %} |
| |
| |
| # phone_update.html |
| {% extends 'one.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 %} |
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现