1.建数据库模型-->model.py
from django.db import models class Student(models.Model): name = models.CharField(max_length=32) age = models.CharField(max_length=32) # verbose_name='性别' gender = models.CharField(max_length=32, verbose_name='性别')
2.设置url访问路径-->urls.py
# 导入三个模块文件 from django.contrib import admin from django.urls import re_path from app01 import views # 设置URL路径 urlpatterns = [ re_path('admin/', admin.site.urls), re_path('index/', views.index, name='index'), re_path('show/', views.show, name='show'), re_path('edit/(\d+)', views.edit, name='edit'), ]
3.创建一个网页-->student.html
<div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <!-- 核心代码 ~ 开始 --> <form action="{% url 'edits' %}" method="post"> {% csrf_token %} <table class="table table-striped table-hover table-bordered"> <!-- 表头 --> <thead> <tr> <th> <label for="id_select_th"></label> <input type="checkbox" id="id_select_th"> </th> <th>主键</th> <th>姓名</th> <th>年龄</th> <th>性别</th> <th>操作</th> </tr> </thead> <!-- 表内容,通过后台传来的数据循环渲染 --> <tbody> {% for student in data_list %} <tr> <td> <label for="id_select_td"></label> <input type="checkbox" class="id_select_td" id="id_select_td" name="id_select_list" value="{{ student.pk }}"> </td> <td>{{ student.pk }}</td> <td>{{ student.name }}</td> <td>{{ student.age }}</td> <td>{{ student.gender }}</td> <td> <a href="{% url 'edit' student.pk %}{{ next }}" class="btn btn-primary btn-sm">编辑</a> </td> </tr> {% endfor %} </tbody> </table> </form> <!-- 分页显示代码,注意循环体的循环对象是Pagination提供的data_list --> <div class="pull-right" style="padding-right: 10px"> <ul class="pagination pagination-sm"> {{ page_obj.page_html|safe }} </ul> </div> <!-- 核心代码 ~ 结束 --> </div> </div> </div>
4.创建Form表单-->forms.py
# <!-------------------------------------------------------------------- # Student表单 # ---------------------------------------------------------------------> class StudentList(forms.ModelForm): class Meta: # 对应的Model中的类 model = models.Student # __all__表示列出所有的字段 fields = '__all__' # 排除的字段 exclude = None # 自定义在前段显示的名字 # labels = None labels = { 'name': '账号', 'age': '年龄', } # 帮助提示信息 help_texts = None # 自定义插件 # widgets = None widgets = { 'name': widgets.Textarea(attrs={'class': 'c1'}) } # 自定义错误信息 error_messages = { 'name': {'required': "用户名不能为空", }, 'age': {'required': "年龄不能为空", }, } # 为每个字段统一添加form-control属性 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) for filed in self.fields.values(): filed.widget.attrs.update({'class': 'form-control'})
5.视图函数-->views.py
# 列表数据展示页面
def show(request): # 判断是否为GET请求 if request.method == 'GET': # 获取当前url,含参数:/show/?page=3; request.path获取当前url,不含参数. path = request.get_full_path() # 拼接路径:?next=/show/?page=3 next = "?next=%s" % path # 通过过滤条件筛选符合要求的数据 student_list = models.Student.objects.all() # <!----------------------------- 分页代码 ----------------------------- # 通过前台获取请求页面的page值 current_page = request.GET.get("page") # 通过数据库获取数据总条数 record_count = student_list.count() # 设置每页显示数据条数 page_record_limit = 3 # 设置显示的最多页面数 page_count_limit = 3 # 类Pagination实例化 page_obj = Pagination(current_page=current_page, record_count=record_count, page_record_limit=page_record_limit, page_count_limit=page_count_limit, request=request) # 数据库截取可客户请求的数据片段 data_list = student_list[page_obj.start:page_obj.end] # 返回页面,page_obj是分页器的一个实例化对象,可以调用类里面的方法 # ------------------------------ 分页代码结束 ------------------------------> return render(request, 'show.html', {'data_list': data_list, 'next': next, 'page_obj': page_obj})
def edit(request, edit_id): # 1.获取请求页面带的next键值 path1 = request.GET.get('next') # 2.找到要操作的表记录,注意:别忘记first() student_obj = models.Student.objects.filter(pk=edit_id).first() # 2.1如果没有找到,原路返回 if not student_obj: return redirect(path1) # 2.2如果找到,渲染页面默认数据 if request.method == 'GET': student_list = StudentList(instance=student_obj) return render(request, 'edit.html', {'student_list': student_list}) else: student_list = StudentList(request.POST, instance=student_obj) if student_list.is_valid(): student_list.save() return redirect(path1)
6.组件
#!/usr/bin/env python # -*- coding:utf-8 -*- import copy class Pagination(object): # 封装分页相关数据 def __init__(self, request, current_page, record_count, page_record_limit, page_count_limit): """ :param page_count: 总页数 :param record_count: 数据总个数 :param page_range: 页的范围 :param page_count_limit: 最多显示页面 :param page_record_limit: 每页显示的行数 :param page_record_list: 页面数据列表 :param current_page: 当前页 :param page_mid: 页面显示页码中间位置页码 """ self.params = copy.deepcopy(request.GET) # 当前页码 try: current_page = int(current_page) if current_page <= 1: current_page = 1 except Exception as e: current_page = 1 self.current_page = current_page # 数据总个数 self.record_count = record_count # 每页显示的行数 self.page_record_limit = page_record_limit # 总页数(数据总个数record_count / 每页显示的行数page_record_limit) # [数据总个数]对[每页显示的行数]取余,如果余数为0,总页数等于商,否则等于商+1 page_count, tmp = divmod(record_count, page_record_limit) if tmp: page_count += 1 self.page_count = page_count else: self.page_count = page_count # 页面页数显示限制(要奇数,便于对称显示) self.page_count_limit = page_count_limit # 每页第一条数据 @property def start(self): return (self.current_page - 1) * self.page_record_limit # 每页最后一条数据 @property def end(self): return self.current_page * self.page_record_limit def page_range(self): # 如果,总页码[小于]最多显示页面: if self.page_count <= self.page_count_limit: page_start = 1 page_end = self.page_count + 1 # 如果,总页码[大于]最多显示页面: else: # 页面显示页码中间位置页码 self.page_mid = int(self.page_count_limit - 1) // 2 if self.current_page <= self.page_mid: page_start = 1 page_end = self.page_count_limit + 1 else: if (self.current_page + self.page_mid) > self.page_count: page_start = self.page_count - self.page_count_limit + 1 page_end = self.page_count + 1 else: page_start = self.current_page - self.page_mid page_end = self.current_page + self.page_mid + 1 return range(page_start, page_end) # 页面显示页码的控制 def page_html(self): # 准备页面渲染的数据 page_record_list = [] # 首页 first_page = '<li><a href="?page=%s">首页</a></li>' % (1,) page_record_list.append(first_page) # 处理上一页 if self.current_page <= 1: prev_page = '<li class="disabled"><a href="#">上一页</a></li>' else: prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,) page_record_list.append(prev_page) ################ 点击页码保留搜索条件 ################ # 页码显示部分 for i in self.page_range(): self.params["page"] = i if i == self.current_page: temp = '<li class="active"><a href="?%s">%s</a></li>' % (self.params.urlencode(), i) else: temp = '<li><a href="?%s">%s</a></li>' % (self.params.urlencode(), i,) page_record_list.append(temp) ################ 点击页码保留搜索条件 ################
# 处理下一页 if self.current_page >= self.page_count: next_page = '<li class="disabled"><a href="#">下一页</a></li>' else: next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,) page_record_list.append(next_page) # 尾页 last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.page_count,) page_record_list.append(last_page) return ''.join(page_record_list)