Python全栈之路-Django(十五)
1 Form组件之老师操作
urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^classes/', views.classes),
url(r'^add_class/', views.add_class),
url(r'^edit_class/(\d+)/', views.edit_class),
url(r'^students/', views.students),
url(r'^add_student/', views.add_student),
url(r'^edit_student/(\d+)/', views.edit_student),
url(r'^teachers/', views.teachers),
url(r'^add_teacher/', views.add_teacher),
url(r'^edit_teacher/(\d+)/', views.edit_teacher),
]
app01.views.py
class TeacherForm(Form):
tname = fields.CharField(min_length=2)
# xx = fields.CharField(
# widget=widgets.Select(
# choices=models.Classes.objects.values_list('id', 'title'),
# attrs={'multiple': 'multiple'}
# )
# widget=widgets.SelectMultiple(
# choices=models.Classes.objects.values_list('id', 'title'),
# )
# )
# xx = fields.ChoiceField(
# choices=models.Classes.objects.values_list('id','title'),
# widget=widgets.SelectMultiple
# )
xx = fields.MultipleChoiceField(
choices=models.Classes.objects.values_list('id','title'),
widget=widgets.SelectMultiple
)
def __init__(self,*args,**kwargs): # 解决数据无法动态显示的Bug,推荐使用
super(TeacherForm,self).__init__(*args,**kwargs)
self.fields['xx'].widget.choices=models.Classes.objects.values_list('id','title')
def teachers(request):
tea_list = models.Teacher.objects.all()
return render(request, 'teachers.html', {'tea_list': tea_list})
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():
xx = obj.cleaned_data.pop('xx')
row = models.Teacher.objects.create(**obj.cleaned_data)
row.c2t.add(*xx)
return redirect('/teachers/')
else:
print(obj.errors)
return render(request, 'add_teacher.html', {'obj': obj})
def edit_teacher(request, nid):
if request.method == 'GET':
row = models.Teacher.objects.filter(id=nid).first()
cls_id = row.c2t.values_list('id')
id_list = list(zip(*cls_id))[0] if list(zip(*cls_id)) else []
obj = TeacherForm(initial={'tname': row.tname,'xx': id_list})
return render(request, 'edit_teacher.html',{'obj':obj,'nid':nid})
else:
obj = TeacherForm(request.POST)
if obj.is_valid():
xx = obj.cleaned_data.pop('xx')
models.Teacher.objects.filter(id=nid).update(**obj.cleaned_data)
row = models.Teacher.objects.filter(id=nid).first()
row.c2t.set(xx)
return redirect('/teachers/')
else:
return render(request, 'edit_teacher.html',{'obj':obj,'nid':nid})
templates.teachers.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>老师列表</h1>
<p><a href="/add_teacher/">添加</a></p>
<table>
<thead>
<tr>
<td>ID</td>
<td>老师姓名</td>
<td>任教班级</td>
<td>操作</td>
</tr>
</thead>
<tbody>
{% for t in tea_list %}
<tr>
<td>{{ t.id }}</td>
<td>{{ t.tname }}</td>
<td>
{% for item in t.c2t.all %}
{{ item.title }}
{% endfor %}
</td>
<td><a href="/edit_teacher/{{ t.id }}/">编辑</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<ul>
</ul>
</body>
</html>
templates.add_teacher.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>添加老师</h1>
<form action="/add_teacher/" method="post">
{% csrf_token %}
<p>
姓名:{{ obj.tname }}
</p>
<p>
班级:{{ obj.xx }}
</p>
<input type="submit" value="提交">
</form>
</body>
</html>
templates.edit_teacher.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>编辑老师</h1>
<form action="/edit_teacher/{{ nid }}/" method="post" novalidate>
{% csrf_token %}
<p>{{ obj.tname }}</p>
<p>{{ obj.xx }}</p>
<input type="submit" value="提交">
</form>
</body>
</html>
2 Form组件
2.1 单选框和多选框
多选框:
cls_id = fields.MultipleChoiceField(
choices=models.Classes.objects.values_list('id','title'),
widget=widgets.SelectMultiple
)
单选框:
cls_id_id = fields.IntegerField(
widget=widgets.Select(
choices=models.Classes.objects.all().values_list('id', 'title'),
attrs={'class': 'form-control'}
)
)
cls_id_id = fields.IntegerField(
widget=widgets.Select(
choices=models.Classes.objects.all().values_list('id', 'title'),
attrs={'class': 'form-control'}
)
)
2.2 Form 其他常用组件
class TestForm(Form):
t1 = fields.CharField(
widget=widgets.Textarea(attrs={})
)
t2 = fields.CharField(
widget=widgets.CheckboxInput
)
t3 = fields.MultipleChoiceField(
choices=[(1, 'basketball'),(2, 'football'),(3, 'voliball')],
widget=widgets.CheckboxSelectMultiple
)
t4 = fields.ChoiceField(
choices=[(1,'basketball'),(2,'football'),(3,'voliball')],
widget=widgets.RadioSelect
)
t5 = fields.CharField(
widget=widgets.PasswordInput(attrs={})
)
t6 = fields.FileField(
widget=widgets.FileInput
)
def test(request):
obj = TestForm({'t3': [2, 3], })
return render(request,'test.html',{'obj':obj})
2.3 Form组件扩展
- is_valid
- 字段 = 默认正则表达式
- 额外的正则
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(
validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
)
- clean_字段,必须返回值
- clean()
有返回值:cleaned_data = 返回值
无返回值:cleaned_data = 原来的值
2.4 Form组件文件上传
import os
def f1(request):
if request.method == 'GET':
return render(request, 'f1.html')
else:
file_obj = request.FILES.get('fafafa')
print(type(file_obj))
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:
file_obj = request.FILES.get('fafafa')
obj = F2Form(data=request.POST,files=request.FILES)
print(type(file_obj))
print(file_obj.name)
print(file_obj.size)
f = open(os.path.join('static', file_obj.name), 'wb')
if obj.is_valid():
print(obj.cleaned_data)
print(obj.cleaned_data.get('fafafa').name)
print(obj.cleaned_data.get('fafafa').size)
f = open(os.path.join('static', obj.cleaned_data.get('fafafa').name), 'wb')
for chunk in obj.cleaned_data.get('fafafa'):
f.write(chunk)
f.close()
return render(request, 'f2.html', {'obj': obj})
else:
print(obj.errors)
return render(request, 'f2.html', {'obj': obj})