s14_07_Form_基础
FORM
- Django的Form主要具有一下几大功能:
生成HTML标签
验证用户数据(显示错误信息)
HTML Form提交保留上次提交数据
初始化页面显示内容
- 小试牛刀
1、创建Form类
from django.forms import Form
from django.forms import widgets
from django.forms import fields
class MyForm(Form):
user = fields.CharField(
widget=widgets.TextInput(attrs={'id': 'i1', 'class': 'c1'})
)
gender = fields.ChoiceField(
choices=((1, '男'), (2, '女'),),
initial=2,
widget=widgets.RadioSelect
)
city = fields.CharField(
initial=2,
widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))
)
pwd = fields.CharField(
widget=widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
)
2、View函数处理
from django.shortcuts import render, redirect
from .forms import MyForm
def index(request):
if request.method == "GET":
obj = MyForm()
return render(request, 'index.html', {'form': obj})
elif request.method == "POST":
obj = MyForm(request.POST, request.FILES)
if obj.is_valid():
values = obj.clean()
print(values)
else:
errors = obj.errors
print(errors)
return render(request, 'index.html', {'form': obj})
else:
return redirect('http://www.google.com')
3、生成HTML
<form action="/" method="POST" enctype="multipart/form-data">
<p>{{ form.user }} {{ form.user.errors }}</p>
<p>{{ form.gender }} {{ form.gender.errors }}</p>
<p>{{ form.city }} {{ form.city.errors }}</p>
<p>{{ form.pwd }} {{ form.pwd.errors }}</p>
<input type="submit"/>
</form>
- 动态select数据
user_type = fields.ChoiceField(
# choices=[(1,'普通用户'),(2,'超级用户')],
# choices=models.UserType.objects.values_list('id','name'),
# 增加后无法更新,静态字段
choices=[],
widget = widgets.Select
)
user_type2 = fields.CharField(widget=widgets.Select(choices=[]))
# 解决方法二
user_type3 = ModelChoiceField(
empty_label='请选择用户类型',
queryset=models.UserType.objects.all(),
to_field_name='id'
# 依赖 models.py中的 def __str__(self): return self.name
# 否则选项的是对象
)
# 解决方法一(推荐)
def __init__(self,*args,**kwargs):
# 自定义方法,重新获取
super(UserInfoForm,self).__init__(*args,**kwargs)
self.fields['user_type'].choices = models.UserType.objects.values_list('id','name')
self.fields['user_type2'].widget.choices = models.UserType.objects.values_list('id','name')
- 数据验证(强大)
验证顺序:
字段:
正则 ==> clean_fields
整体:
clean ==> _post_clean
源码查找:
is_valid() errors full_clean _clean_fields clean_fields
_clean_form clean
_post_clean
整体错误信息:
‘__all__’ 'NON_FIELD_ERRORS'
代码示例:
class LoginForm(forms.Form):
user =fields.CharField()
pwd =fields.CharField()
# 需整体显示错误信息
def clean_user(self):
c = models.UserInfo.objects.filter(name=self.cleaned_data['user']).count()
if not c:
return self.cleaned_data['user']
else:
raise ValidationError('用户名已经存在',code='xxx')
def clean_pwd(self):
return self.cleaned_data['pwd']
def clean(self):
c = models.UserInfo.objects.filter(name=self.cleaned_data['user'],pwd=self.cleaned_data['pwd']).count()
if c:
return self.clean_data
else:
raise ValidationError('用户名或密码错误')
def _post_clean(self):
pass
- 序列化
关于Django中的序列化主要应用在将数据库中检索的数据返回给客户端用户,
特别的Ajax请求一般返回的为Json格式。
1、serializers
from django.core import serializers
ret = models.BookType.objects.all()
data = serializers.serialize("json", ret)
2、json.dumps
import json
#ret = models.BookType.objects.all().values('caption')
ret = models.BookType.objects.all().values_list('caption')
ret=list(ret)
result = json.dumps(ret)
3、由于json.dumps时无法处理datetime日期,所以可以通过自定义处理器来做扩展,如:
import json
from datetime import date
from datetime import datetime
class JsonCustomEncoder(json.JSONEncoder):
def default(self, field):
if isinstance(field, datetime):
return o.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(field, date):
return o.strftime('%Y-%m-%d')
else:
return json.JSONEncoder.default(self, field)
# ds = json.dumps(d, cls=JsonCustomEncoder)
示例:
# djang 默认序列化
# from django.core import serializers
# ret = models.UserType.objects.all()
# data = serializers.serialize("json", ret)
# return HttpResponse(data)
# 自定制
import json
v = models.UserType.objects.values_list('id','name')
v=list(v)
return HttpResponse(json.dumps(v))
- ErrorDict
- 自定义encoder
- QuerySet
第一种:
from django.core import serializers
v = models.tb.objects.all()
data = serializers.serialize("json", v)
第二种:
如果有时间进行排除处理。
import json
from datetime import date
from datetime import datetime
class JsonCustomEncoder(json.JSONEncoder):
def default(self, field):
if isinstance(field, datetime):
return field.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(field, date):
return field.strftime('%Y-%m-%d')
else:
return json.JSONEncoder.default(self, field)
v = models.tb.objects.values('id','name','ctime')
v = list(v)
v = json.dumps(v,cls=JsonCustomEncoder)
- FORM 代码
# views.py
from django import forms
from django.forms import widgets
from django.forms import fields
class FM(forms.Form):
# 字段本身只做验证
user = fields.CharField(
error_messages={'required':'用户名不能为空'},
widget= widgets.Textarea(attrs={'class':'c1'}),
label='用户名',
initial='root',
)
pwd =fields.CharField(
max_length=12,
min_length=6,
error_messages={'required':'密码不能为空',
'min_length':'密码长度不能小于6位',
'max_length':'密码长度不能超过12位'},
widget=widgets.PasswordInput
)
email = fields.EmailField(error_messages={'required':'用户名不能为空','invalid':'邮箱格式错误'})
from app01 import models
def fm(request):
if request.method=='GET':
obj = FM()
return render(request,'fm.html',{'obj':obj})
elif request.method =='POST':
# 获取数据,验证
# 成功后获取正确数据,失败显示错误信息
obj =FM(request.POST)
if obj.is_valid():
print(obj.cleaned_data)
# models.Userinfo.bojects.create(**cleaned_data)
else:
# print(obj.errors)
# print(obj.errors.as_json())
# print(obj.errors['user'][0])
return render(request,'fm.html',{'obj':obj})
# html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="/fm/"method="POST">
{% csrf_token %}
<p>{{ obj.user.label }}{{ obj.user }}{{ obj.errors.user.0 }}</p>
<p>{{ obj.pwd }}{{ obj.errors.pwd.0 }}</p>
<p>{{ obj.email }}{{ obj.errors.email.0 }}</p>
{# {{ obj.as_p }}#}
{# {{ obj.as_ul }}#}
{# <table>{{ obj.as_table }}</table>#}
<p><input type="submit"></p>
</form>
</body>
</html>