Django框架之Modelform
作用--根据模型类生成form类
创建modelform
# 首先导入ModelForm,modelsform需要继承这个类
from django.forms import ModelForm
# 假如模型中有个Student类,我们为他创建一个模型类
class Student(ModelForm):
class Meat: # 在这个类中再写一个原类Meta(规定)
model = models.Student #对应的Model中的类
fields = "__all__" #字段,如果是__all__,就是表示列出所有的字段
exclude = None #排除的字段
labels = None #提示信息
help_texts = None #帮助提示信息
widgets = None #自定义插件
error_messages = None #自定义错误信息
#error_messages用法:
error_messages = {
'name':{'required':"用户名不能为空",},
'age':{'required':"年龄不能为空",},
}
#widgets用法,比如把输入用户名的input框给为Textarea
#首先得导入模块
from django.forms import widgets as wid #因为重名,所以起个别名
widgets = {
"name":wid.Textarea(attrs={"class":"c1"}) #还可以自定义属性
}
#labels,自定义在前端显示的名字
labels= {
"name":"用户名"
}
这个类的使用简直是和form一模一样
渲染
只需要实例化这个类,把对象交给模板,模板就可以渲染出对应的输入框
def student(request):
if request.method == 'GET':
student_list = StudentList()
return render(request,'student.html',{'student_list':student_list})
循环这个对象得到student,放在页面上是一个个input框,student.label是数据库中每个字段的verbose_name ,如果没有设置这个属性,拿到的默认就是字段名,还可以通过student.errors.0 拿到错误信息
提交保存
保存数据的时候,不必再去post请求中去拿那些数据,直接save()就可以写入数据库,而且还可以验证,如果错误可以不刷新页面,简直和form一模一样
def student(request):
if request.method == 'GET':
student_list = StudentList()
return render(request,'student.html',{'student_list':student_list})
else:
student_list = StudentList(request.POST)
if student_list.is_valid(): # 验证
student_list.save() # 提交
return redirect()
return render(request,'student_list.html',{'student_list':student_list})
编辑数据
之前编辑数据时,要取到一条数据的对象,获得他的信息再传递到模板.
而使用modelform你只要拿到这条数据的对象,再把他交给modelform就可以在模板中显示其信息
def student_edit(request,pk):
obj = models.Student.objects.filter(pk=pk).first()
if not obj:
return redirect('test')
if request.method == "GET":
student_list = StudentList(instance=obj)
return render(request,'student_edit.html',{'student_list':student_list})
编辑的提交
编辑的提交不同于上面的提交,如果仍使用上面的方法,那么就会生成一条数据而不是修改一条数据,如果想要修改一条数据,就要告诉他要修改那条数据.就需要把数据对象也传给他
def student_edit(request,pk):
obj = models.Student.objects.filter(pk=pk).first()
...同上
else:
student_list = StudentList(request.POST,instance=obj) # 传入数据及对象
if student_list.is_valid():
student_list.save()
return render(request,'student_edit.html',{'student_list':student_list})
modelform与model的关系
modelform 下的字段对象都是 model转化过去的 每个字段都是BoundField的实例对象,而不是form下的类似于ModelChoiceField的实例对象 打印这个字段对象的到的是对应的标签字符串 BoundFieldObj.name 是form字段名 BoundFieldObj.field 是form字段对应类的对象 ModelChoiceField这种form字段对象接收一个queryset是模型类对应的queryset 可以通过queryset取出模型类 # 这三个类是继承关系 class ChoiceField(Field): class ModelChoiceField(ChoiceField): class ModelMultipleChoiceField(ModelChoiceField):
...
# 模型类
class Book(models.Model): # "book"
title=models.CharField(verbose_name="标题",max_length=32)
price=models.DecimalField(verbose_name="价格",decimal_places=2,max_digits=5,default=12) # 999.99 1000
state=models.IntegerField(choices=((1,"已出版"),(2,"未出版")) ,default=1)
publish=models.ForeignKey(verbose_name="出版社",to="Publish",default=1)
authors=models.ManyToManyField(to='author',default=1)
def __str__(self):
return self.title
# modelform类
class BookModelForm(ModelForm):
class Meta:
model=Book
fields="__all__"
error_messages={
"title":{"required":"不能为空"},
"price":{"required":"不能为空"},
}
a = BookModelForm()
# 取最后一个字段
for i in a:
b=i
print(b)
#<select name="authors" required id="id_authors" multiple="multiple">
# <option value="1" selected>alex</option>
# <option value="2">egon</option>
# <option value="3">yuan</option>
# <option value="4">yuan</option>
#</select>
print(type(b))
# <class 'django.forms.boundfield.BoundField'>
print(b.name) # 字段的名字
# authors
print(b.field) # form中的一个字段类的实例
# <django.forms.models.ModelMultipleChoiceField object at 0x000001F930BCE278>
print(b.field.queryset) # 对应字段的全部对象,对应的,对应的,而不是本类中的对象
#<QuerySet [<author: alex>, <author: egon>, <author: yuan>, <author: yuan>]>
print(b.field.queryset.model) # 使用queryset获得类名
# <class 'app01.models.author'>

浙公网安备 33010602011771号