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>

 

posted @ 2018-05-16 10:55  G500  阅读(280)  评论(0)    收藏  举报