Python-Django 项目模块-年级模块开发(七)

Python-django 自定义模块开发-列表展示

第四章 Django 自定义模块-年级模块开发过程

前言

这一系列文章是通过一个简单的学校项目进行演示的,项目中遇到的问题将一一记录下来,仅供参考。

[En]

This series of articles is demonstrated by a simple school project, and the problems encountered in the project will be recorded one by one for reference only.

此处学习版本 python3.8 django 4.0.6 bootstrap3 开发工具 VSCODE

一、创建静态页面-年级首页

对应的路径:school\school_web_grade\templates\grade\grade_index.html

{% load i18n static %}

<html>

<head>
<title>年级管理title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />


<link rel="stylesheet" href="{% static 'bootstrap-3.4.1/css/bootstrap.min.css' %}" />


<link rel="stylesheet" href="{% static 'bootstrap-3.4.1/css/bootstrap-theme.min.css' %}" />
<script src="{% static 'js/jquery-3.2.1/jquery.min.js' %}">script>
<script src="{% static 'js/popper-1.15.0/umd/popper.min.js' %}">script>

<script src="{% static 'bootstrap-3.4.1/js/bootstrap.min.js' %}">script>







<style type="text/css">


style>
head>

<body>
<div class="container-fluid">

<div class="row">

<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container-fluid">

<div class="navbar-header">

<a class="navbar-brand" href="{% url 'school_web_grade:index'%}" style="padding-top:5px;">
<img alt="Brand" src="{% static 'images/ico.png' %}" />
a>
<a class="navbar-brand" href="{% url 'school_web_grade:index'%}">陕西家里蹲大学师生信息管理系统a>
div>

<div>
<ul class="nav navbar-nav" id="ul_menu_top">
<li><a href="{% url 'school_web_grade:gradeIndex' pageIndex=1 %}">年级管理a>li>
<li><a href="#">学科管理a>li>
<li><a href="#">教师管理a>li>
<li><a href="#">班级管理a>li>
<li><a href="#">学生管理a>li>
ul>
div>

<ul class="nav navbar-nav navbar-right">
<li><a href="#"><span class="glyphicon glyphicon-user">span> 注册a>li>
<li><a href="#"><span class="glyphicon glyphicon-log-in">span> 登录a>li>
<li>
<a href="javascript:void(0)" onclick="openModalWindow()">
<span class="glyphicon glyphicon-off">span> 退出
a>
li>
ul>
div>
nav>

div>

<div class="row" style="padding-top: 50px;padding-bottom: 50px;">

<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title "><span class=" glyphicon glyphicon-search">span>年级管理查询条件h3>
div>
<div class="panel-body">
<form class="form-inline" id="gradeForm" name="gradeForm" action="{% url 'school_web_grade:gradeIndex' pageIndex=1 %}" method="post">
{% csrf_token %}
<div class="form-group">
<label for="grade_name_id">年级名称:label>
<input type="text" name="grade_name" class="form-control" id="grade_name_id" value="{{grade_name}}" placeholder="请输入年级名称" />
div>

<div class="form-group pull-right">
<button type="submit" class="btn btn-success">查询button>
<a href="javascript:void(0);" onclick="addGrade()" class="btn btn-info" role="button">新增a>
<a href="javascript:void(0);" onclick="openModalWindow()" class="btn btn-info" role="button">弹出框a>
div>
form>
div>
div>
<div class="panel panel-info">
<div class="panel-heading"><span class="glyphicon glyphicon-list">span>数据展示div>
<div class="panel-body">
{% block content %}
<div class="row ">
<table class="table table-striped table-bordered text-center">
<thead>
<tr>
<th class="text-center">当页索引th>
<th class="text-center">编号th>
<th class="text-center">年级名称th>
<th class="text-center">创建日期th>
<th class="text-center">修改日期th>
<th class="text-center">操作th>
tr>
thead>
<tbody>
{% for grade in gradeList %}
<tr class="{% cycle 'info' 'success' as rowcolors %}">
<td>{{ forloop.counter }}td>
<td>{{ grade.grade_id }}td>
<td>{{ grade.grade_name }}td>
<td>{{ grade.grade_create_date|date:"Y-m-d H:i:s" }}td>
<td>{{ grade.grade_update_date|date:"SHORT_DATE_FORMAT" }}td>
<td>
<button type="button" class="btn btn-info btn-xs" data-url="{% url 'school_web_grade:gradeDetail' grade.grade_id %}"
onclick="detailGrade(this)">
<span class="glyphicon glyphicon-zoom-in">span>详情
button>
<button type="button" class="btn btn-warning btn-xs" data-url="{% url 'school_web_grade:loadGradeEdit' grade.grade_id %}" onclick="editGrade(this)" >
<span class="glyphicon glyphicon-pencil">span>修改
button>
<button type="button" class="btn btn-danger btn-xs" data-url="{% url 'school_web_grade:gradeDelete' grade.grade_id %}" onclick="deleteGrade(this)" >
<span class="glyphicon glyphicon-remove">span>删除
button>
td>
tr>
{% empty %}
<tr class="success">
<td colspan="6">没有查询到数据...td>
tr>
{% endfor %}

tbody>
table>
div>

<div class="row">

<nav aria-label="Page navigation" class="text-center">
<ul class="pagination">

{% if currentGradePage.has_previous == True %}
<li><a href="javascript:void(0);" data-url="{% url 'school_web_grade:gradeIndex' pageIndex=1 %}" aria-label="Previous"><span aria-hidden="true">首页span>a>li>
<li><a href="javascript:void(0);" data-url="{% url 'school_web_grade:gradeIndex' pageIndex=pageIndex|add:-1 %}" aria-label="Previous"><span aria-hidden="true">上一页span>a>li>
{% else %}
<li class="disabled"><span aria-hidden="true">首页span>li>
<li class="disabled"><span aria-hidden="true">上一页span>li>
{% endif%}

<li class="active"><span aria-hidden="true">{{ pageIndex}}span>li>

{% if currentGradePage.has_next == True %}
<li><a href="javascript:void(0);" data-url="{% url 'school_web_grade:gradeIndex' pageIndex|add:1 %}" aria-label="Next"><span aria-hidden="true">下一页span>a>li>
<li><a href="javascript:void(0);" data-url="{% url 'school_web_grade:gradeIndex' pageIndex=currentGradePage.paginator.num_pages %}" aria-label="Next"><span aria-hidden="true">尾页span>a>li>
{% else %}
<li class="disabled"><span aria-hidden="true">下一页span>li>
<li class="disabled"><span aria-hidden="true">尾页span>li>
{% endif %}
<li class="disabled"><span aria-hidden="true">共 {{currentGradePage.paginator.count}} 条span>li>
ul>
nav>
div>
{% endblock %}
div>
div>

div>
<div class="row navbar navbar-default navbar-fixed-bottom" style="text-align: center; height: 40px;">
<div class="bg-success" style="height: 100% ;padding-top: 15px;">
版权所有@copyRight 2013-2022 口袋里的小龙 开发框架 python3.8 bootstrap-3 Django4
div>
div>
div>

<div class="modal fade " id="modalWindowDiv" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×button>
<h4 class="modal-title" id="myModalLabel">
模态框(Modal)标题
h4>
div>
<div class="modal-body">
按下 ESC 按钮退出。
<form>
<div class="form-group">
<label for="recipient-name" class="control-label">Recipient:label>
<input type="text" class="form-control" id="recipient-name">
div>
<div class="form-group">
<label for="message-text" class="control-label">Message:label>
<textarea class="form-control" id="message-text">textarea>
div>
form>
div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭
button>
<button type="button" class="btn btn-primary">
提交更改
button>
div>
div>
div>
div>

<script type="text/javascript">
$(document).ready(function () {
// 在这里写你的代码...
$('#showDetail').modal('hide')
//菜单点击事件
$("#ul_menu_top li").click(function () {
//清除样式
$("#ul_menu_top li").removeClass("active");
//设置选中颜色
$(this).addClass("active");
console.log($(this));
});
//表单提交
$(".pagination li a").click(function(){
var data_url = $(this).attr("data-url");
$("#gradeForm").attr("action",data_url);
$("#gradeForm").submit()
});

// hide 方法调用之后立即触发该事件。
$('#modalWindowDiv').on('hidden.bs.modal', function (e) {
// do something...
console.log("hide 方法调用之后立即触发该事件。");
});
//从远端的数据源加载完数据之后触发该事件
$('#modalWindowDiv').on('loaded.bs.modal', function (e) {
// do something...
console.log("从远端的数据源加载完数据之后触发该事件");
});
//show 方法调用之后立即触发该事件。如果是通过点击某个作为触发器的元素,则此元素可以通过事件的 relatedTarget 属性进行访问。
$('#modalWindowDiv').on('show.bs.modal', function (e) {
// do something...
console.log("show 方法调用之后立即触发该事件");
});
//此事件在模态框已经显示出来(并且同时在 CSS 过渡效果完成)之后被触发。如果是通过点击某个作为触发器的元素,则此元素可以通过事件的 relatedTarget 属性进行访问。
$('#modalWindowDiv').on('shown.bs.modal', function (e) {
// do something...
console.log("此事件在模态框已经显示出来(并且同时在 CSS 过渡效果完成)之后被触发");
});


});

/**
* 模态窗口打开的方法
*/
function openModalWindow() {
//打开模态窗口的方法 手动打开模态框。在模态框显示之前返回到主调函数中
$('#modalWindowDiv').modal('show');

//手动隐藏模态框。在模态框隐藏之前返回到主调函数中
// $('#modalWindowDiv').modal('hide')
}
//添加
function addGrade() {
window.open("{% url 'school_web_grade:gradeAdd' %}");
}
//详情
function detailGrade(_this) {
console.log($(_this).attr("data-url"));
var url = $(_this).attr("data-url");
window.open(url);
}
/**
* 表单提交
*/
function deleteGrade(_this) {
console.log($(_this).attr("data-url"));
var url = $(_this).attr("data-url");
$("#gradeForm").attr("action",url);
$("#gradeForm").submit();

// window.open(url);
}
//修改
function editGrade(_this) {
console.log($(_this).attr("data-url"));
var url = $(_this).attr("data-url");
window.open(url);
}

script>
body>

html>

先创建页面 我再解释 其中的用法

1.指定国际化

{% load i18n static %}


<link rel="stylesheet" href="{% static 'bootstrap-3.4.1/css/bootstrap.min.css' %}" />

2.指定静态文件引用地址{% static ” %} 固定写法

{% static 'bootstrap-3.4.1/css/bootstrap.min.css' %}


<a class="navbar-brand" href="{% url 'school_web_grade:index'%}">陕西家里蹲大学师生信息管理系统a>

3.对应的url请求写法

{% url 'school_web_grade:index'%}其中 {% url 'x:y'%} 为固定写法  "x:y"号中是对应的模块:对应的方法名

4.对应url请求参数

<li><a href="{% url 'school_web_grade:gradeIndex' pageIndex=1 %}">年级管理a>li>

参数的写法是 在请求的url 后面输写 可以写 pageIndex=1 也可以写 1 也可以是个变量 pageIndex

5.数据的展示

<tbody>
{% for grade in gradeList %}
<tr class="{% cycle 'info' 'success' as rowcolors %}">
<td>{{ forloop.counter }}td>
<td>{{ grade.grade_id }}td>
<td>{{ grade.grade_name }}td>
<td>{{ grade.grade_create_date|date:"Y-m-d H:i:s" }}td>
<td>{{ grade.grade_update_date|date:"SHORT_DATE_FORMAT" }}td>
<td>
<button type="button" class="btn btn-info btn-xs" data-url=""
onclick="detailGrade(this)">
<span class="glyphicon glyphicon-zoom-in">span>详情
button>
<button type="button" class="btn btn-warning btn-xs" data-url="" onclick="editGrade(this)" >
<span class="glyphicon glyphicon-pencil">span>修改
button>
<button type="button" class="btn btn-danger btn-xs" data-url="" onclick="deleteGrade(this)" >
<span class="glyphicon glyphicon-remove">span>删除
button>
td>
tr>
{% empty %}
<tr class="success">
<td colspan="6">没有查询到数据...td>
tr>
{% endfor %}

tbody>

二、后端代码编写

1.创建实体类 model.py

from django.db import models'''模型定义类'''# Create your models here.'''年级类'''class SchoolGrade(models.Model):    '''    erbose_name: str | None = ..., 备注字段名    name: str | None = ...,     primary_key: bool = ...,   是否主键 如果设置为 True ,将该字段设置为该模型的主键    max_length: int | None = ..., 最大长度    unique: bool = ..., 是否唯一    blank: bool = ..., 是否为空    null: bool = ...,是否为null    db_index: bool = ..., 数据索引    rel: ForeignObjectRel | None = ...,     default: Any = ..., 默认值    editable: bool = ...,     serialize: bool = ..., 是否序列化    unique_for_date: str | None = ..., 唯一日期    unique_for_month: str | None = ..., 唯一月    unique_for_year: str | None = ..., 唯一年    choices: _FieldChoices | None = ...,     help_text: str = ..., 这个字段设置后 随 表单一起显示    db_column: str | None = ...,  数据库列    db_tablespace: str | None = ..., 数据库表空间    auto_created: bool = ...,     validators: Iterable[_ValidatorCallable] = ...,     error_messages: _ErrorMessagesT | None = ...    '''    ##  自动生成值得列 如果不设置 primary_key 则会自动生成一个 id 字段 添加到此模型中作为主键自动生成    grade_id = models.BigAutoField(unique=True,serialize=True,primary_key=True,null=False,blank=False,verbose_name="年级表主键")    ## 设置年级名称 max_length 最大长度为500     grade_name = models.CharField(max_length=500,verbose_name="年级名称")    ## 设置创建时间    grade_create_date = models.DateTimeField(auto_now_add=True,verbose_name="创建时间")    ## 设置修改时间    grade_update_date = models.DateTimeField(auto_now_add=True,verbose_name="修改时间")

2.生成数据库表

执行命令:

python .\manage.py makemigrations school_web_gradepython .\manage.py migrate

3.创建业务调用类 views.py

该方法中有一些参数的说明和用法。你可以自己试一试。

[En]

There are descriptions and usage of some parameters in the method. You can try it yourself.

import datetimefrom django.shortcuts import redirect, renderfrom django.views import generic## python 分页from django.core.paginator import Paginator## 引入 年级模型from .models import SchoolGrade# Create your views here.## 调用视图的方法类'''通用视图类 默认主页'''class IndexView(generic.ListView):    ## 调用的视图    template_name="index.html"    ## 此方法必须有 返回None 都可以     def get_queryset(self):        return None'''方法实现'''def index(request):    return render(request=request,template_name="index.html")'''年级管理'''## 年级首页def gradeIndex(request,pageIndex):    page_index = pageIndex    print(page_index)    object_list = []    grade_name = ""    if request.method == "POST":        ## 获取数据的方法        grade_name = request.POST.get("grade_name")        print(grade_name)        ## 修改时间        # grade_update_date = datetime.datetime.now()        ## __contains like 查询        object_list = SchoolGrade.objects.filter(grade_name__contains=grade_name).order_by("grade_create_date")    else:        ## 查询年级数据        object_list = SchoolGrade.objects.order_by("grade_create_date")       # ## 获取总行数    # count = SchoolGrade.objects.order_by("grade_create_date").count()    # print("获取总行数",count)    '''    object_list: _SupportsPagination, 数据列表    per_page: int | str, 每页显示的条数    orphans: int = ...,  可选的。当你不希望最后一页的项目数量很少时,使用这个选项。如果最后一页的项目数量通常小于或等于 orphans,那么这些项目将被添加到前一页(成为最后一页),而不是让这些项目单独留在一页上。例如,如果有 23 个条目,per_page=10,orphans=3,则会有两页;第一页有 10 个条目,第二页(也是最后一页)有 13 个条目。orphans 默认为 0,这意味着页面永远不会合并,最后一页可能只有一个项目。    allow_empty_first_page: bool = ... 是否允许页面为空    '''    ## 每页显示的条数 必要的。一个页面中包含的最大项目数    per_page = 2    ## 可选的。是否允许第一页为空。 如果 False 并且 object_list 是空的,则会出现 EmptyPage 错误    allow_empty_first_page = True    paginator = Paginator(object_list=object_list,per_page=per_page,allow_empty_first_page=True)    # print("paginator",paginator)    ## 读取当页数据对象    currentGradePage = paginator.page(page_index)    gradeList = currentGradePage.object_list    ## 获取查询页的数据    # for a in currentGradePage.object_list:    #     print(a)    print("paginator.count-总行数",paginator.count)    print("paginator.count-总页数",paginator.num_pages)    ## 以 1 为基础的页码范围迭代器    print("paginator.count-以1为基础循环",paginator.page_range)    '''    返回页码 列表    number: int | float | str = ..., *, on_each_side: int = ..., on_ends: int = ...    '''    # iterators = paginator.get_elided_page_range(1,on_each_side=3,on_ends=2)    # for p in iterators:    #     print(p)    # ## 输入页码 返回 page对象    # page = paginator.get_page(1)    # print(page)    # ## 如果有下一页,返回 True。    # has_next = page.has_next()    # print("has_next:",has_next)    # ## 如果有上一页返回true    # has_previous = page.has_previous()    # print("has_previous:",has_previous)    # ## 如果有 上一页或者下一页 返回true    # has_other_pages = page.has_other_pages()    # print("has_other_pages:",has_other_pages)    # ## 返回下一页的页码。如果下一页不存在,则引发 InvalidPage    # next_page_number = page.next_page_number()    # print("next_page_number:",next_page_number)    # ## 返回上一页的页码。如果上一页不存在,则引发 InvalidPage    # previous_page_number = page.previous_page_number()    # print("previous_page_number:",previous_page_number)    # ## 返回页面上第一个对象,相对于分页器列表中所有对象的基于 1 的索引。例如,当对一个有 5 个对象的列表进行分页时,每页有 2 个对象,第二页的 start_index() 将返回 3    # start_index = page.start_index()    # print("start_index:",start_index)    # ##  返回页面上最后一个对象相对于分页器列表中所有对象的基于 1 的索引。例如,当对一个有 5 个对象的列表进行分页时,每页有 2 个对象,第二页的 end_index() 将返回 4    # end_index = page.end_index()    # print("end_index:",end_index)    # print(pageIndex)    ## 保存变量    context = {"gradeList":gradeList,"currentGradePage":currentGradePage,"pageIndex":pageIndex,"grade_name":grade_name}    return render(request=request,template_name="grade/grade_index.html",context=context,content_type='text/html')

4.配置路由地址 urls.py

"""school_web_grade URL ConfigurationThe urlpatterns list routes URLs to views. For more information please see:    https://docs.djangoproject.com/en/4.0/topics/http/urls/Examples:Function views    1. Add an import:  from my_app import views    2. Add a URL to urlpatterns:  path('', views.home, name='home')Class-based views    1. Add an import:  from other_app.views import Home    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')Including another URLconf    1. Import the include() function: from django.urls import include, path    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))"""from django.contrib import adminfrom django.urls import pathfrom django.urls import includefrom . import views## 模块名称 url命名空间app_name = "school_web_grade"'''path(route: str, route 是一个匹配 URL 的准则(类似正则表达式)view: (...) -> HttpResponseBase,当 Django 找到了一个匹配的准则,就会调用这个特定的视图函数,并传入一个 HttpRequest 对象作为第一个参数,被"捕获"的参数以关键字参数的形式传入kwargs: Dict[str, Any] = ...,任意个关键字参数可以作为一个字典传递给目标视图函数name: str = ...为你的 URL 取名能使你在 Django 的任意地方唯一地引用它,尤其是在模板中。这个有用的特性允许你只改一个文件就能全局地修改某个 URL 模式'''urlpatterns = [    ## 默认主页    path(route="",view=views.IndexView.as_view(),name="index"),    ## 年级模块    path(route="gradeIndex//",view=views.gradeIndex,name="gradeIndex"),]

5.注册 school\school_web_grade\admin.py

from django.contrib import admin# Register your models here.## 向管理网站注册当前创建的模型from .models import SchoolGrade## 年级类admin.site.register(SchoolGrade)

6.运行项目

Python-Django 项目模块-年级模块开发(七)

总结

初次运行 数据是不存在的 因为没有对数据库进行添加数据操作 ,下一节专门介绍下 新增

Original: https://blog.51cto.com/u_15446828/5507893
Author: 口袋里的小龙
Title: Python-Django 项目模块-年级模块开发(七)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/513265/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球