Python-django 自定义模块开发
第四章 Django 自定义模块-使用默认表单在项目中的使用
前言
本系列文章以一个简单的学校项目来做演示,项目中遇到的问题会一一记录下来,仅供学习参考使用
此处学习版本 python3.8 django 4.0.6 bootstrap3 开发工具 VSCODE
一、Django 使用自定义表单
首先需要创一个forms.py文件
from django import forms
'''
学生类表单
'''
class StudentForm(forms.Form):
'''
*,
max_length: int | None = ..., 最大长度
min_length: int | None = ..., 最小长度
strip: bool = ...,
empty_value: str | None = ...,
required: bool = ..., 是否必须
widget: Widget | Type[Widget] | None = ...,
label: str | None = ..., 标签对应的字段中文
initial: Any | None = ..., 初始值
help_text: str = ..., 帮助提示文字
error_messages: _ErrorMessagesT | None = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
localize: bool = ...,
disabled: bool = ..., 是否禁用
label_suffix: str | None = ...
'''
## 学生名称
student_name = forms.CharField(max_length=500,label='学生名称',help_text="请输入学生姓名",initial="")
## 学生性别
student_sex = forms.CharField(max_length=500,label="性别",help_text="请输入学生性别",initial="")
## 学生所在的年级
grade_id = forms.IntegerField(label="年级",help_text="请选择学生所在的年级",initial="")
## 学生所在的班级
class_id = forms.IntegerField(label="班级",help_text="请选择学生所在的班级",initial="")
## 重写默认方法 对空值进行重新定义
def clean(self):
cleaned_data = {}
for key,value in self.cleaned_data.items():
if value == None:
cleaned_data[key] = self.fields[key].initial
else:
cleaned_data[key] = value
return cleaned_data
引入form表单配置
views.py
## 引入学生表单
from .forms import StudentForm
## 新增
def studentAdd(request):
## 使用 django自带标签初始化表单
if request.method != "POST":
studentForm = StudentForm()
print(studentForm)
## 年级
schoolGradeList = SchoolGrade.objects.order_by("grade_create_date")
## 班级
gradeClassesList = GradeClasses.objects.filter().order_by("class_create_date")
context = {"studentForm":studentForm,"gradeClassesList":gradeClassesList,"schoolGradeList":schoolGradeList}
return render(request=request,template_name="student/student_add.html",context=context)
urls.py
## 新增
path(route="studentAdd",view=views.studentAdd,name="studentAdd"),
models.py
'''
学生类
'''
class Student(models.Model):
## 学生主键
student_id = models.BigAutoField(unique=True,serialize=True,primary_key=True,null=False,blank=False,verbose_name="学生表主键")
## 学生姓名
student_name = models.CharField(max_length=500,verbose_name="学生姓名")
## 学生性别
student_sex = models.CharField(max_length=500,verbose_name="学生性别")
## 学生所在的年级
grade_id = models.IntegerField(null=True,blank=True,verbose_name="年级表主键")
## 学生所在的班级
class_id = models.IntegerField(null=True,blank=True,verbose_name="班级表主键")
## 设置创建时间
student_create_date = models.DateTimeField(auto_now_add=True,verbose_name="创建时间")
## 设置修改时间
student_update_date = models.DateTimeField(null=True,auto_now_add=False,verbose_name="修改时间")
student_add.html
<!-- 公用布局页 功用页引用必须放在最上边 -->
{% extends "student/student_header.html" %}
{% load i18n static %}
<!DOCTYPE html>
<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" />
<!-- 静态地址引入方式-->
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1/css/bootstrap.min.css' %}" />
<!-- 程序引入方式 -->
<!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<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>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="{% static 'bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
<!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
<!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
<!-- HTML5 Shiv 和 Respond.js 用于让 IE8 支持 HTML5元素和媒体查询 -->
<!--[if lt IE 9]>
<script src="/static/js/html5shiv-3.7.0/html5shiv.js"></script>
<script src="/static/js/respond-1.4.2/respond.min.js"></script>
<![endif]-->
<style type="text/css">
</style>
</head>
<body>
<div class="container-fluid">
<!-- Columns start at 50% wide on mobile and bump up to 33.3% wide on desktop -->
{% block content %}
<div class="row" style="padding-top: 50px;padding-bottom: 50px;">
<!-- 中间内容区域 -->
<div class="panel panel-info ">
<div class="panel-heading"><span class="glyphicon glyphicon-plus"></span>学生管理-添加数据</div>
<div class="panel-body">
<form class="form-horizontal" id="studentForm" name="studentForm" action="{% url 'school_web_grade:studentSave' %}" method="post">
{% csrf_token %}
{% comment "代码注释: 自动渲染表单有很大的问题 样式问题 所以要手动渲染" %}
{{studentForm}}
{ {% endcomment %}
<div class="form-group">
<label for="{{studentForm.student_name.id_for_label}}" class="col-sm-2 control-label">{{ studentForm.student_name.label }}:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="{{studentForm.student_name.id_for_label}}" name="{{ studentForm.student_name.html_name }}" value="{{ studentForm.student_name.value }}" placeholder="{{studentForm.student_name.help_text }}">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="inputError">{{ studentForm.student_sex.label }}:</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="{{ studentForm.student_sex.html_name }}" id="student_sex_0" value="0">男
</label>
<label class="radio-inline">
<input type="radio" name="{{ studentForm.student_sex.html_name }}" id="student_sex_1" value="1">女
</label>
</div>
</div>
<div class="form-group">
<label for="{{studentForm.grade_id.id_for_label}}" class="col-sm-2 control-label">{{ studentForm.grade_id.label }}:</label>
<div class="col-sm-10">
<select id="{{studentForm.grade_id.id_for_label}}" class="form-control" name="{{ studentForm.grade_id.html_name }}" placeholder="{{studentForm.grade_id.help_text }}">
<option value="">--请选择--</option>
{% if schoolGradeList %}
{% for grade in schoolGradeList %}
<option value="{{grade.grade_id}}">{{grade.grade_name}}</option>
{% endfor %}
{% endif %}
</select>
</div>
</div>
<div class="form-group">
<label for="{{studentForm.class_id.id_for_label}}" class="col-sm-2 control-label">{{ studentForm.class_id.label }}:</label>
<div class="col-sm-10">
<select id="{{studentForm.class_id.id_for_label}}" class="form-control" name="{{ studentForm.class_id.html_name }}" placeholder="{{studentForm.class_id.help_text }}">
<option value="">--请选择--</option>
{% if gradeClassesList %}
{% for clazz in gradeClassesList %}
<option value="{{clazz.class_id}}">{{clazz.class_name}}</option>
{% endfor %}
{% endif %}
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="reset" class="btn btn-info">重 置</button>
<button type="submit" class="btn btn-success">保 存</button>
</div>
</div>
</form>
<div class="row" >
<div class="col-md-6 col-md-offset-3">
<!-- 消息框 成功 fade in -->
{% if result == 1 %}
<div name="message_alert" class="alert alert-success alert-dismissible" role="alert" >
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<strong>提示:</strong> 新增成功!
</div>
{% elif result == 2 %}
<div name="message_alert" class="alert alert-warning alert-dismissible" role="alert" >
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<strong>提示:</strong> 数据已存在!
</div>
{% elif result < 0 %}
<div name="message_alert" class="alert alert-danger alert-dismissible" role="alert" >
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<strong>提示:</strong> 新增失败!
</div>
{% endif %}
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
});
</script>
</div>
{% endblock %}
</div>
</body>
</html>
二、Django 默认表单
使用表单模板
您只需将表单实例放到模板的上下文中即可。因此,如果您的表单在上下文中叫 form
,那么 {{ form }}
将渲染它相应的 <label>
和 <input>
元素。
表单渲染选项
{{ form.as_table }}
以table 标签显示表单{{ form.as_p }}
以p标签显示表单{{ form.as_ul }}
以ul标签显示表单
如果你使用默认表单 在页面会生成对应的标签 如下:
<p><label for="id_subject">Subject:</label>
<input id="id_subject" type="text" name="subject" maxlength="100" required></p>
<p><label for="id_message">Message:</label>
<textarea name="message" id="id_message" required></textarea></p>
<p><label for="id_sender">Sender:</label>
<input type="email" name="sender" id="id_sender" required></p>
<p><label for="id_cc_myself">Cc myself:</label>
<input type="checkbox" name="cc_myself" id="id_cc_myself"></p>
这种标签学习一下就可以了 对于我们项目中的样式 表单的统一 就显得格格不入了,所以才要使用自定义表单手动渲染来进行使用,至此介绍完成,希望对你有所帮助
form属性的使用
{{ field.label }}
字段的label
{{ field.id_for_label }}
用于该字段的 ID
{{ field.value }}
字段的值
{{ field.html_name }}
字段名称
{{ field.help_text }}
与该字段关联的帮助文本。
{{ field.errors }}
输出一个 <ul class="errorlist">
,其中包含这个字段的所有验证错误信息。你可以使用 {% for error in field.errors %}
循环来自定义错误信息的显示。在这种情况下,循环中的每个对象是包含错误信息的字符串。
{{ field.is_hidden }}
如果是隐藏字段,这个属性为 True
,否则为 False