Form 组件:ChoiceField、MultiplChoiceFiedld、常用插件、解决Form动态添加BUG、From 验证流程、额外正则添加、Form 扩展钩子函数、文件上传
1、Form 组件、Form动态添加BUG
ChoiceField、MultiplChoiceFiedld
def teacher_list(request):
if request.method == 'GET':
tdata = models.Teacher.objects.all()
print(tdata)
# print(tdata.tname)
return render(request,'teacher_list.html',{'tdata':tdata})
teacher_list.html :
<body>
<h1>老师列表</h1>
<div><a href="/add_teacher/">添加</a></div>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>老师姓名</th>
<th>任教班级</th>
</tr>
</thead>
<tbody>
{% for row in tdata %}
<tr>
<td>{{ row.id }}</td>
<td>{{ row.tname }}</td>
<td>None-----</td>
<td><a href="/edit_teacher/{{ row.id }}">编辑</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
class TeacherForm(Form):
tname = fields.CharField(min_length=2)
# 下面写法只能获取到单个字 (因为相当于request.POST.get('xx'))
# xx = fields.CharField(
# widget=widgets.Select(choices=models.Classes.objects.values_list('id','title'),attrs={'multiple':'multiple'})
# )
# 获取多个值用下面写法(多选的select下拉框): choices 写在外面,用 MultipleChoiceField类型
xx = fields.MultipleChoiceField(
choices=models.Classes.objects.values_list('id', 'title'),
widget=widgets.SelectMultiple
)
# 解决Form动态添加BUG:
def __init__(self,*args,**kwargs):
super(TeacherForm,self).__init__(*args,**kwargs)
self.fields['xx'].choices = models.Classes.objects.values_list('id','title')
def add_teacher(request):
if request.method == 'GET':
obj = TeacherForm()
return render(request,'add_teacher.html',{'obj':obj})
else:
obj = TeacherForm(request.POST)
if obj.is_valid():
print(obj.cleaned_data)
xx = obj.cleaned_data.pop('xx')
print(obj.cleaned_data)
row = models.Teacher.objects.create(**obj.cleaned_data)
print(xx)
row.c2t.add(*xx)
return redirect('/teacher_list/')
return render(request, 'add_teacher.html', {'obj': obj})
def edit_teacher(request,tid):
if request.method == 'GET':
row = models.Teacher.objects.filter(id=tid).first()
class_ids = row.c2t.values_list('id')
id_list = list(zip(*class_ids))[0] if list(zip(*class_ids)) else []
obj = TeacherForm(initial={'tname':row.tname,'xx':id_list})
return render(request,'edit_teacher.html',{'obj':obj})
2、常用插件
CheckBox # 单选: xx = fields.CharField(
widget=widgets.CheckboxInput
)
# 多选: xx = field.MultipleChoiceField(
choices=[(1,'篮球'),(2,'足球')],
widget=widgets.CheckboxSelectMultiple
)
radio # 互斥只能单选: xx = fields.ChoiceField(
choices=[(1,'篮球'),(2,'足球')],
widget=widgets.RadioSelect
)
input
textarea # xx = fields.CharField(widget=widgets.Textarea(attrs={自定属性}))
File # 上传文件 : xx = fields.FileField(
widget=widgets.FileInput
)
3、Form验证流程、钩子扩展函数、额外正则添加
# From 验证流程
# 额外正则添加: 以下为要用的库:
#from django.forms import Form,widgets,fields
from django.core.validators import RegexValidator
# Form 扩展钩子函数:
# 源码:self._clean_fields()
# self._clean_form()
# self._post_clean()
# 验证流程:先遍历字段,把每一个字段进行验证,验证通过后执行对应字段的函数,函数返回值,赋值给self.clean_data
from django.core.exceptions import ValidationError # 抛出异常需要用到此类
class TestForm(Form):
user = fields.CharField(
# 额外正则 (在默认正则外进行的正则验证)
validators=[RegexValidator(r'^[0-9]+$','请输入数字'),RegexValidator(r'^159[0-9]+$','数字必须159开头')]
)
pwd = fields.CharField()
# 验证通过后会调用字段对应的函数:
def clean_user(self):
v = self.cleaned_data['user']
if models.Student.objects.filter(name=v).count():
# 异常类需要导入使用
raise ValidationError('用户名已经存在',code='invalid')
else:
pass
# 函数必须要有返回值
return self.cleaned_data['user']
def clean_pwd(self):
return self.cleaned_data['pwd']
# 这个函数在 以上字段正则校验完成后才会执行
def clean(self):
# 如果要对整体数据进行验证的话,可适用于此函数
# 例:
user = self.cleaned_data.get('user')
email = self.cleaned_data.get('emai')
if models.Student.objects.filter(name=user,email=email).count():
raise ValidationError('用户名或邮箱已存在')
# 如果返回值为空,则不重新赋值cleaned_data。否则重新赋值
return self.cleaned_data
# 用不着,需要自己写异常处理等。了解即可
def _post_clean(self):
pass
def test(request):
obj = TestForm()
return render(request,'test.html',{"obj":obj})
4、文件上传
def f1(request):
if request.method == 'GET':
return render(request,'f1.html')
else:
import os
file_obj = request.FILES.get('fafafa')
print(file_obj.name)
print(file_obj.size)
# 按块循环取文件内容:
f = open(os.path.join('static',file_obj.name),'wb')
for chunk in file_obj.chunks():
f.write(chunk)
f.close()
return render(request, 'f1.html')
class F2Form(Form):
user = fields.CharField()
fafafa = fields.FileField()
def f2(request):
if request.method == 'GET':
obj = F2Form()
return render(request,'f2.html',{'obj':obj})
else:
obj = F2Form(request.POST,files=request.FILES)
if obj.is_valid():
f2_file = obj.cleaned_data.get('fafafa')
print(f2_file.name)
print(f2_file.size)
return render(request,'f2.html',{'obj':obj})
f1.html
<body>
<form method="POST" action="/f1/" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="fafafa">
<input type="submit" value="提交">
</form>
</body>

浙公网安备 33010602011771号