ModelForm组件的应用
ModelForm 组件的创建:
1.创建一个类,该类继承 forms.ModelForm
2.大致组成部分
class ModelNameModelForm(forms.ModelForm):
class Meta:
model =需要校正的模型类名
例:model = models.Book
fields=" __all__" 或 fields=["字段名”,........] 选择需要展示或校正的字段
error_messages={
"字段名”:{“required”: "此字段不能为空”},
"字段名”:{“required”: "此字段不能为空”},
.........
}
from django.forms import widgets as wid
widgets={
"字段名":wid.TextInput(attrs={"input标签属性":"属性值"}),
"price":wid.TextInput(attrs={"class":"form-control"}),
"pub_date":wid.DateInput(attrs={"class":"form-control","type":"date"}),
}
labels={
"字段名”:“别名”,
“title” :“书籍名称”,
}
#钩子,进一步校正函数
def clean_字段名(self):
val = self.cleaned_data.get("字段名”)
if 符合条件:
return val
else:
raise ValidationError("想要说明的错误信息”)
3.应用
用的时候只需要 :
form = ModelNameModelForm(需要校正的数据字典)
例:
1.直接展示空的input的标签(get请求时)
form = BookModelForm( ) #直接展示,渲染出空内容的input 标签
# form = BookModelForm(instance=edit_book) 编辑情况下
2.用户提交数据,需校正时,可以展示错误的提示信息 (post请求时)
form = BookModelForm(request.POST ) #校正前端通过post请求的提交的数据
##form = BookModelForm(request.POST,instance=edit_book) 编辑情况下
if form.is_vaild():
form.save()
redirect("/book/")
else:
return render(request, 'addbook.html', locals())
实例
1.model .py :(模型类 Book为例)
from django.db import models # Create your models here. from django.db import models # Create your models here. class Book(models.Model): title = models.CharField( max_length=32,verbose_name="书籍名称") pub_date=models.DateField(verbose_name="出版日期") price=models.DecimalField(max_digits=5,decimal_places=2,verbose_name="价格") publish=models.ForeignKey(to="Publish",to_field="id",on_delete=models.CASCADE,null=True,verbose_name="出版社") authors=models.ManyToManyField("Author",db_table="book2authors",verbose_name="作者") # 创建关系表 def __str__(self): return self.title class Meta: verbose_name="书籍"
2.views.py(构建ModelForm组件)
form django import forms
from django.forms import widgets as wid
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
class BookModelForm(forms.ModelForm): class Meta: model = models.Book fields="__all__" #默认页面渲染时 显示所有的字段 # fields=["title","price"] #需要显示的字段
#错误信息 error_messages={ "title":{"required":"书名不能为空"}, "price":{"required":"价格不能为空"}, "pub_date":{"required":"日期不能为空"}, "publish":{"required":"出版社不能为空"}, "authors":{"required":"作者不能为空"}, }
#给渲染的input标签设置type类型和相关的属性
widgets={ "title":wid.TextInput(attrs={"class":"form-control"}), "price":wid.TextInput(attrs={"class":"form-control"}), "pub_date":wid.DateInput(attrs={"class":"form-control","type":"date"}), }
#字段别名设置 labels={ "title":"书籍名称",
}
#钩子函数,进一步进行约束
#对title字段进行约束 def clean_title(self): val=self.cleaned_data.get("title") if val.isdigit(): raise ValidationError("书名不能为纯数字!") else: return val
#对price字段进行约束
def clean_price(self):
val=self.cleaned_data.get("price")
if val.isdigit():
return val
else:
raise ValidationError("价格必须为数字")
3.views.py视图函数中:
后端添加视图函数:用ModelForm组件实现页面渲染 (红色字体部分)
def addbook(request): if request.method=="POST": ''' data=request.POST.dict() data.pop("csrfmiddlewaretoken") data.pop("author_list") book=models.Book.objects.create(**data) # 保证提交键值对的键必须和数据库表字段一致 # 为书籍绑定作者关系 author_list=request.POST.getlist("author_list") print(author_list) # ['1', '2'] book.authors.add(*author_list) ''' form=BookModelForm(request.POST) if form.is_valid(): form.save() return redirect("/books/") else: return render(request, 'addbook.html', locals()) else: # form=BookForm() # forms组件 form=BookModelForm() # modelforms组件 return render(request,'addbook.html',locals())
前端添加页面:
<div class="container-fluid"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <h3>添加{{ table_name }}</h3> <form action="" method="post" novalidate> {% csrf_token %} {% for field in form %} <div> <label for="">{{ field.label }}</label> {{ field }}<span class="error pull-right">{{ field.errors.0 }}</span> </div> {% endfor %} <input type="submit" class="btn btn-primary"> </form> </div> </div> </div>
后端编辑视图:
def editbook(request,edit_book_id): edit_book = models.Book.objects.filter(pk=edit_book_id).first() if request.method=="POST": # 方式1: # title=request.POST.get("title") # price=request.POST.get("price") # pub_date=request.POST.get("pub_date") # publish_id=request.POST.get("publish_id") # author_list=request.POST.getlist("author_list") # models.Book.objects.filter(pk=edit_book_id).update(title=title,price=price,pub_date=pub_date,publish_id=publish_id) # update只有queryset才能调用 # edit_book.authors.set(author_list) # 方式2: # data=request.POST.dict() # data.pop("csrfmiddlewaretoken") # author_list=data.pop("author_list") # models.Book.objects.filter(pk=edit_book_id).update(**data) # 保证提交键值对的键必须和数据库表字段一致 # # 为书籍绑定作者关系 # author_list=request.POST.getlist("author_list") # edit_book.authors.set(author_list) # 方式3 form = BookModelForm(request.POST,instance=edit_book)#编辑时,instance=edit_book 传进去就可以该对象信息在页面的展示,这是编辑和添加页面的区别之处 if form.is_valid():, form.save() return redirect("/books/") else: return render(request, 'editbook.html', locals()) else: form=BookModelForm(instance=edit_book) return render(request,'editbook.html',locals())
前端编辑页面渲染代码:
<div class="container-fluid"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <h3>编辑{{ table_name }}</h3> <form action="" method="post" novalidate> {% csrf_token %} {% for field in form %} <div> <label for="">{{ field.label }}</label> {{ field }}<span class="error pull-right">{{ field.errors.0 }}</span> </div> {% endfor %} <input type="submit" class="btn btn-primary"> </form> </div> </div> </div>