class UserForm(dforms.Form):
username = fields.CharField()
email = fields.EmailField()
<form action="/edit_user-{{ nid }}/" method="POST" novalidate>
{% csrf_token %}
<p>{{ obj.username }}{{ obj.errors.username.0 }}</p>
<p>{{ obj.email }}{{ obj.errors.email.0 }}</p>
<input type="submit" value="提交" />
</form>
def edit_user(request,nid):
if request.method == "GET":
data = models.UserInfo.objects.filter(id=nid).first()
# 这一步必须,创建Form对象,返回给前端
obj = UserForm({'username':data.username,'email':data.email})
return render(request,'edit_user.html',{'obj':obj,'nid':nid})
else:
# 接受表单数据,生成UserForm对象
obj = UserForm(request.POST)
if obj.is_valid():
# 如果验证成功,clean_data就是表单数据的字典形式
models.UserInfo.objects.filter(id=nid).update(**obj.cleaned_data)
return redirect('/users/')
else:
return render(request,'edit_user.html',{'obj':obj,'nid':nid})
- 字段
ChoiceField ***** 下拉
MultipleChoiceField 下拉,多选
CharField
IntegerField
DecimalField 小数
DateField
DateTimeField
EmailField
GenericIPAddressField IP
FileField 上传文件
Field本质上是一个widgest插件和一个正则表达式
widget = widgets.TextInput(attrs={'class':'c1'}), # 定制HTML插件
widget=widgets.Select(choices=[(1,'刚娘'),(2,'铁娘'),(3,'钢弹')])
常用插件
http://www.cnblogs.com/haiyan123/p/7795771.html
class LoveForm(forms.Form):
price = fields.IntegerField()
user_id = fields.IntegerField(
# widget=widgets.Select(choices=[(0,'alex'),(1,'刘皓宸'),(2,'杨建'),])
widget=widgets.Select()
)
user_id2 = ModelChoiceField(
queryset=models.UserInfo.objects.all(),
to_field_name='id'
)
def __init__(self,*args,**kwargs):
# 拷贝所有的静态字段,复制给self.fields
super(LoveForm,self).__init__(*args,**kwargs)
self.fields['user_id'].widget.choices = models.UserInfo.objects.values_list('id', 'username')
def love(request):
obj = LoveForm()
return render(request,'love.html',{'obj':obj})
from django.forms.models import ModelChoiceField
from django.forms.models import ModelChoiceField
class LoveForm(forms.Form):
price = fields.IntegerField()
user_id2 = ModelChoiceField(
queryset=models.UserInfo.objects.all(),
to_field_name='id'
)
注意:依赖models中的str方法
1.简单扩展
利用Form组件自带的正则扩展:
a. 方式一
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator
class MyForm(Form):
user = fields.CharField(
error_messages={'invalid': '...'},
validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
)
b. 方式二
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator
class MyForm(Form):
user = fields.RegexField(r'^[0-9]+$',error_messages={'invalid': '...'})
2.基于源码流程
a. 单字段
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
class AjaxForm(forms.Form):
username = fields.CharField()
user_id = fields.IntegerField(
widget=widgets.Select(choices=[(0,'alex'),(1,'刘皓宸'),(2,'杨建'),])
)
# 自定义方法 clean_字段名
# 必须返回值self.cleaned_data['username']
# 如果出错:raise ValidationError('用户名已存在')
def clean_username(self):
v = self.cleaned_data['username']
if models.UserInfo.objects.filter(username=v).count():
# 整体错了
# 自己详细错误信息
raise ValidationError('用户名已存在')
return v
def clean_user_id(self):
return self.cleaned_data['user_id']
b. 整体错误验证
class AjaxForm(forms.Form):
username = fields.CharField()
user_id = fields.IntegerField(
widget=widgets.Select(choices=[(0,'alex'),(1,'刘皓宸'),(2,'杨建'),])
)
# 自定义方法 clean_字段名
# 必须返回值self.cleaned_data['username']
# 如果出错:raise ValidationError('用户名已存在')
def clean_username(self):
v = self.cleaned_data['username']
if models.UserInfo.objects.filter(username=v).count():
# 整体错了
# 自己详细错误信息
raise ValidationError('用户名已存在')
return v
def clean_user_id(self):
return self.cleaned_data['user_id']
def clean(self):
value_dict = self.cleaned_data
v1 = value_dict.get('username')
v2 = value_dict.get('user_id')
if v1 == 'root' and v2==1:
raise ValidationError('整体错误信息')
return self.cleaned_data
PS: _post_clean
注:重写clean方法是对form整体的进行验证(是为了了出来多个字段连个唯一的场景),他在字段验证之后执行,字段验证的错误信息的key为字段名称,整体验证的错误信息的key为__all__,可以使用obj.error.__all__点出来value
源码:
try:
if isinstance(field, FileField):
initial = self.get_initial_for_field(field, name)
value = field.clean(value, initial)
else:
value = field.clean(value)
self.cleaned_data[name] = value
if hasattr(self, 'clean_%s' % name):
value = getattr(self, 'clean_%s' % name)()
self.cleaned_data[name] = value
except ValidationError as e:
self.add_error(name, e)
from django.core import serializers
ret = models.BookType.objects.all()
data = serializers.serialize("json", ret)
result['data'] = data
json.dumps(result)
import json
#ret = models.BookType.objects.all().values('caption')
ret = models.BookType.objects.all().values_list('caption')
ret=list(ret)
result = json.dumps(ret)
重点:python json.dumps()只能处理基本数据类型
注意:request.POST 中存放的参数
request.FILES 中存放的文件
def upload_file(request):
if request.method == 'GET':
return render(request, 'form/upload.html')
else:
file = request.FILES.get('img')
filename = file.name
f = open(filename,"wb")
for line in file.chunks():
f.write(line)
f.close()
return HttpResponse("提交成功")
from django import forms
from django.forms import fields
class UploadForm(forms.Form):
user = fields.CharField()
img = fields.FileField()
def upload(request):
if request.method == 'GET':
return render(request,'upload.html')
else:
obj = UploadForm(request.POST,request.FILES)
if obj.is_valid():
user = obj.cleaned_data['user']
img = obj.cleaned_data['img']
<!--user = request.POST.get('user')-->
<!--img = request.FILES.get('img')-->
# img是对象(文件大小,文件名称,文件内容。。。)
print(img.name)
print(img.size)
f = open(img.name,'wb')
for line in img.chunks():
f.write(line)
f.close()
return HttpResponse('...')