一、Form
form.py
from django import forms
from django.core.exceptions import ValidationError
from django.contrib.auth.models import User
import re
# 定义手机号验证规则
def phone_validate(value):
phone = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
if not phone.match(value):
raise ValidationError("手机号格式错误")
class RegForm(forms.Form):
username = forms.CharField(
label="用户名",
min_length=6,
initial="请输入用户名",
error_messages={
'required': "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短6位"
},
widget=forms.widgets.TextInput(attrs={"class": "form-control"})
)
password = forms.CharField(
label="密码",
min_length=8,
widget=forms.widgets.PasswordInput(attrs={"class": "form-control"}, render_value=True),
error_messages={
"required": "不能为空",
"min_length": "不能少于8位"
}
)
re_password = forms.CharField(
label="密码",
min_length=8,
widget=forms.widgets.PasswordInput(attrs={"class": "form-control"}, render_value=True),
error_messages={
"required": "不能为空",
"min_length": "不能少于8位"
}
)
email = forms.EmailField(
label="邮箱",
widget=forms.widgets.TextInput(attrs={"class": "form-control"}),
error_messages={
'required': "不能为空",
"invalid": "格式错误",
}
)
# radio
gender = forms.fields.ChoiceField(
choices=((1,"男"),(0,"女"),),
label="性别",
initial=1,
widget=forms.widgets.RadioSelect()
)
# 单选select
se_hobby = forms.fields.ChoiceField(
label="select单选爱好",
choices=((1,"篮球"),(2,"网球"),(3,"羽毛球"),),
# initial=1,
widget=forms.widgets.Select()
)
# 多选select
se_hobbys = forms.fields.MultipleChoiceField(
label="select多选爱好",
choices=((1, "篮球"), (2, "网球"), (3, "羽毛球"),),
initial=[1,],
widget=forms.widgets.SelectMultiple()
)
# 单选checkbox
keep_username = forms.fields.ChoiceField(
label="记住用户名",
# initial="checked",
widget=forms.widgets.CheckboxInput()
)
# 多选checkbox
ch_hobbys = forms.fields.MultipleChoiceField(
label="checkbox多选爱好",
choices=((1, "篮球"), (2, "网球"), (3, "羽毛球"),),
# initial=[1, 2],
widget=forms.widgets.CheckboxSelectMultiple()
)
# 手机号
phone = forms.fields.CharField(
validators=[phone_validate, ],
error_messages={
"required": "手机不能为空"
},
widget=forms.widgets.TextInput(attrs={"class": "form-control"})
)
# # 批量增加样式
# def __init__(self, *args, **kwargs):
# super(RegForm, self).__init__(*args, **kwargs)
# for field in iter(self.fields):
# self.fields[field].widget.attrs.update({
# 'class': 'form-control'
# })
#
# # 动态获取数据库的choice数据
# self.fields["gender"].choices = User.objects.all().values_list("id", "gender")
# 重写全局的钩子函数,对确认密码做校验
def clean(self):
password = self.cleaned_data.get("password")
re_password = self.cleaned_data.get("re_password")
if re_password and re_password != password:
self.add_error("re_password", ValidationError("两次输入的密码不一致"))
else:
return self.cleaned_data
# 定义局部钩子,验证用户名是否被注册
def clean_username(self):
username = self.cleaned_data.get("username")
is_exist = User.objects.filter(username=username)
if is_exist:
self.add_error("username", ValidationError("用户名已被注册"))
else:
return username
# 定义局部钩子,验证邮箱是否可用
def clean_email(self):
email = self.cleaned_data.get("email")
is_exist = User.objects.filter(email=email)
if is_exist:
self.add_error("email", ValidationError("邮箱不可用"))
else:
return email
view.py
def reg(request):
form_obj = RegForm()
if request.method == "POST":
ret = {"status": 0, "msg": ""}
form_obj = RegForm(request.POST)
if form_obj.is_valid():
# form_obj.cleaned_data.pop("re_password")
# print(form_obj.cleaned_data)
# User.objects.create_user(**form_obj.cleaned_data)
ret["msg"] = "/login"
return JsonResponse(ret)
else:
# print(form_obj.errors)
ret["status"] = 1
ret["msg"] = form_obj.errors
return JsonResponse(ret)
return render(request, 'register.html', {"forms_obj": form_obj})
register.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta http-equiv='Content-type' content='text/htm'>
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<script class="lazy" data-src="/static/jquery-3.3.1.js"></script>
<script class="lazy" data-src="/static/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3 reg-form">
<h3 class="text-center">Register</h3><br>
<form class="form-horizontal" novalidate method="post"
enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group ">
<label for='{{ forms_obj.username.id_for_label }}'
class="col-sm-2 control-label">{{ forms_obj.username.label }}</label>
<div class="col-sm-8">
{{ forms_obj.username }}
<span class="help-block">{{ forms_obj.username.errors.0 }}</span>
<span id="ss" class="help-block"></span>
</div>
</div>
<div class="form-group ">
<label for='{{ forms_obj.password.id_for_label }}'
class="col-sm-2 control-label">{{ forms_obj.password.label }}</label>
<div class="col-sm-8">
{{ forms_obj.password }}
<span class="help-block">{{ forms_obj.password.errors.0 }}</span>
</div>
</div>
<div class="form-group ">
<label for='{{ forms_obj.re_password.id_for_label }}'
class="col-sm-2 control-label">{{ forms_obj.re_password.label }}</label>
<div class="col-sm-8">
{{ forms_obj.re_password }}
<span class="help-block">{{ forms_obj.re_password.errors.0 }}</span>
</div>
</div>
<div class="form-group">
<label for="{{ forms_obj.email.id_for_label }}"
class="col-sm-2 control-label">{{ forms_obj.email.label }}</label>
<div class="col-sm-8">
{{ forms_obj.email }}
<span class="help-block">{{ forms_obj.email.errors.0 }}</span>
</div>
</div>
<div class="form-group">
<label for="{{ forms_obj.gender.id_for_label }}"
class="col-sm-2 control-label">{{ forms_obj.gender.label }}</label>
<div class="col-sm-8">
{{ forms_obj.gender }}
<span class="help-block">{{ forms_obj.gender.errors.0 }}</span>
</div>
</div>
<div class="form-group">
<label for="{{ forms_obj.se_hobby.id_for_label }}"
class="col-sm-2 control-label">{{ forms_obj.se_hobby.label }}</label>
<div class="col-sm-8">
{{ forms_obj.se_hobby }}
<span class="help-block">{{ forms_obj.se_hobby.errors.0 }}</span>
</div>
</div>
<div class="form-group">
<label for="{{ forms_obj.se_hobbys.id_for_label }}"
class="col-sm-2 control-label">{{ forms_obj.se_hobbys.label }}</label>
<div class="col-sm-8">
{{ forms_obj.se_hobbys }}
<span class="help-block">{{ forms_obj.se_hobbys.errors.0 }}</span>
</div>
</div>
<div class="form-group">
<label for="{{ forms_obj.keep_username.id_for_label }}"
class="col-sm-2 control-label">{{ forms_obj.keep_username.label }}</label>
<div class="col-sm-8">
{{ forms_obj.keep_username }}
<span class="help-block">{{ forms_obj.keep_username.errors.0 }}</span>
</div>
</div>
<div class="form-group">
<label for="{{ forms_obj.ch_hobbys.id_for_label }}"
class="col-sm-2 control-label">{{ forms_obj.ch_hobbys.label }}</label>
<div class="col-sm-8">
{{ forms_obj.ch_hobbys }}
<span class="help-block">{{ forms_obj.ch_hobbys.errors.0 }}</span>
</div>
</div>
<div class="form-group">
<label for="{{ forms_obj.phone.id_for_label }}"
class="col-sm-2 control-label">{{ forms_obj.phone.label }}</label>
<div class="col-sm-8">
{{ forms_obj.phone }}
<span class="help-block">{{ forms_obj.phone.errors.0 }}</span>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button id="reg_submit" type="button" class="btn btn-success btn-block">注册</button>
</div>
</div>
</form>
</div>
</div>
</div>
<script>
$("#reg_submit").click(function () {
var formData = new FormData();
formData.append("username", $("#id_username").val());
formData.append("password", $("#id_password").val());
formData.append("re_password", $("#id_re_password").val());
formData.append("gender", $("input[name='gender']:checked").val());
formData.append("se_hobby", $("#id_se_hobby").val());
formData.append("se_hobbys", $("#id_se_hobbys").val());
formData.append("keep_username", $("#id_keep_username").prop("checked"));
formData.append("ch_hobbys", $("#id_ch_hobbys input[name='ch_hobbys']:checked").val());
formData.append("phone", $("#id_phone").val());
formData.append("csrfmiddlewaretoken", $("input[name='csrfmiddlewaretoken']").val());
$.ajax({
url:'/register/',
type:'post',
processData: false,
contentType: false,
data:formData,
}).done(function (data) {
if (data.status){
$.each(data.msg,function (k,v) {
$("#id_"+k).next("span").text(v[0]).parent().parent().addClass("has-error")
})
}
else {
window.location.href = data.msg
}
})
});
$("form input").focus(function () {
$(this).next("span").text("").parent().parent().removeClass("has-error");
});
$("form select").focus(function () {
$(this).next("span").text("").parent().parent().removeClass("has-error");
});
$("form input[name='ch_hobbys']").focus(function () {
$(this).parents("ul").next("span").text("").parent().parent().removeClass("has-error");
})
</script>
</body>
</html>
二、ModelForm
form.py
from booktest.models import *
from django.forms import widgets as wds
class BookForm(forms.ModelForm):
class Meta:
model = BookInfo
fields = "__all__"
labels = {
"btitle": "书名",
"bpub_date": "发布日期",
"bcomment": "评论量",
"bread": "阅读量"
}
widgets = {
"btitle": wds.TextInput(attrs={"class": "form-control"}),
"bpub_date": wds.TextInput(attrs={"class": "form-control", "type": "date"}),
"bread": wds.TextInput(attrs={"class": "form-control"}),
"bcomment": wds.TextInput(attrs={"class": "form-control"})
}
error_messages = {
"btitle": {"required":"不能为空",},
"bpub_date": {"required":"不能为空",},
"bcomment": {"required":"不能为空",},
"bread": {"required":"不能为空",}
}
view.py(add_book)
def add_book(request):
form_obj = BookForm()
if request.method == "POST":
ret = {"status": 0, "msg": ""}
form_obj = BookForm(data=request.POST)
if form_obj.is_valid():
print(form_obj.cleaned_data)
form_obj.save()
ret["msg"] = '/bookform'
return JsonResponse(ret)
else:
ret["status"] = 1
ret["msg"] = form_obj.errors
return JsonResponse(ret)
return render(request, 'add_book.html', {"forms_obj": form_obj})
add_book.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta http-equiv='Content-type' content='text/htm'>
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<script class="lazy" data-src="/static/jquery-3.3.1.js"></script>
<script class="lazy" data-src="/static/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3 reg-form">
<h3 class="text-center"></h3><br>
<form class="form-horizontal" novalidate method="post"
enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group ">
<label for='{{ forms_obj.btitle.id_for_label }}'
class="col-sm-2 control-label">{{ forms_obj.btitle.label }}</label>
<div class="col-sm-8">
{{ forms_obj.btitle }}
<span class="help-block">{{ forms_obj.btitle.errors.0 }}</span>
<span id="ss" class="help-block"></span>
</div>
</div>
<div class="form-group ">
<label for='{{ forms_obj.bpub_date.id_for_label }}'
class="col-sm-2 control-label">{{ forms_obj.bpub_date.label }}</label>
<div class="col-sm-8">
{{ forms_obj.bpub_date }}
<span class="help-block">{{ forms_obj.bpub_date.errors.0 }}</span>
</div>
</div>
<div class="form-group ">
<label for='{{ forms_obj.bcomment.id_for_label }}'
class="col-sm-2 control-label">{{ forms_obj.bcomment.label }}</label>
<div class="col-sm-8">
{{ forms_obj.bcomment }}
<span class="help-block">{{ forms_obj.bcomment.errors.0 }}</span>
</div>
</div>
<div class="form-group">
<label for="{{ forms_obj.bread.id_for_label }}"
class="col-sm-2 control-label">{{ forms_obj.bread.label }}</label>
<div class="col-sm-8">
{{ forms_obj.bread }}
<span class="help-block">{{ forms_obj.bread.errors.0 }}</span>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button id="reg_submit" type="button" class="btn btn-success btn-block">注册</button>
</div>
</div>
</form>
</div>
</div>
</div>
<script>
$("#reg_submit").click(function () {
var formData = new FormData();
formData.append("btitle", $("#id_btitle").val());
formData.append("bpub_date", $("#id_bpub_date").val());
formData.append("bcomment", $("#id_bcomment").val());
formData.append("bread", $("#id_bread").val());
formData.append("csrfmiddlewaretoken", $("input[name='csrfmiddlewaretoken']").val());
$.ajax({
url:'/bookform/',
type:'post',
processData: false,
contentType: false,
data:formData,
}).done(function (data) {
if (data.status){
$.each(data.msg,function (k,v) {
$("#id_"+k).next("span").text(v[0]).parent().parent().addClass("has-error")
})
}
else {
window.location.href = data.msg
}
})
});
$("form input").focus(function () {
$(this).next("span").text("").parent().parent().removeClass("has-error");
});
</script>
</body>
</html>
view.py(edit_book)
def editbook(request, book_id):
edit_book = BookInfo.objects.get(id=book_id)
if request.method == "POST":
form_obj = BookForm(request.POST, instance=edit_book)
if form_obj.is_valid():
form_obj.save() # edit_book.update(request.POST)
return redirect('/add_book')
else:
form_obj = BookForm(instance=edit_book)
return render(request, 'edit_book.html', locals())
edit_book.html
<body>
<form method="post">
{% csrf_token %}
{% for field in form_obj %}
<div>
{{ field.label }}
{{ field }}<span>{{ field.errors.0 }}</span>
</div>
{% endfor %}
<input type="submit">
</form>
</body>