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'>

  

posted @ 2018-03-14 15:53  瓜田月夜  阅读(152)  评论(0编辑  收藏  举报