Django 之modelform组件
什么是modelform 组件
针对model对应生成form,它会自动对应model里面的字段并对应生成相应的校验字段和规则
可以先去看form组件,通过form组件能更好的理解modelform组件。(Django 之form组件)
1、前期准备
建表,输入数据,在前端先显示书籍表
class Book(models.Model): name = models.CharField(max_length=32) price = models.DecimalField(max_digits=8, decimal_places=2) publish = models.ForeignKey(to='Publish') authors = models.ManyToManyField(to='Author') def __str__(self): return self.name class Publish(models.Model): name = models.CharField(max_length=32) email = models.EmailField() addr = models.CharField(max_length=32) def __str__(self): # 方便前端打印 return self.name class Author(models.Model): name = models.CharField(max_length=32) choices = [ [1,"男"], [2,"女"], [3,"其它"], ] gender = models.IntegerField(choices=choices, default=1) authorinfo = models.OneToOneField(to="AuthorInfo") def __str__(self): return self.name class AuthorInfo(models.Model): addr = models.CharField(max_length=32) phone = models.CharField(max_length=11) def __str__(self): return self.addr
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" type="text/css" href="/static/bootstrap3/css/bootstrap.min.css"> <script src="/static/bootstrap3/js/bootstrap.min.js"></script> <script src="/static/jquery-3.3.1.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-sm-8 col-sm-offset-2"> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">BOOK</h3> </div> <div class="panel-body"> <a href="/add/" class="btn btn-info">添加</a> <table class="table table-bordered table-striped table-hover"> <thead> <tr> <th>书名</th> <th>价格</th> <th>出版社</th> <th>作者</th> <th>编辑</th> </tr> </thead> <tbody> {% for book in book_list %} <tr> <td>{{ book.name }}</td> <td>{{ book.price }}</td> <td>{{ book.publish }}</td> <td> {% for author in book.authors.all %} {{ author.name }}, {% endfor %} </td> <td><a href="/edit/?id={{ book.id }}" class="btn btn-primary">编辑</a></td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </div> </div> </body> </html>
#分配url和简单视图函数
# urls.py 下
url(r"^book/$", views.book),
url(r"^add/$", views.add),
url(r"^edit/$", views.edit),
# views.py 下
def book(request):
book_list = models.Book.objects.all()
return render(request, "book.html", locals())
2、修改数据
2.1 modelform包含的属性
class BookModelForm(ModelForm): class Meta: model =Book#对应的Model中的类 fields = "__all__" #字段,如果是__all__,表示所有的字段, 也可以是['name', 'price'] exclude = 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":"用户名" } def clean(self): pass
2.2 使用modelform
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" type="text/css" href="/static/bootstrap3/css/bootstrap.min.css"> <script src="/static/bootstrap3/js/bootstrap.min.js"></script> <script src="/static/jquery-3.3.1.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-sm-8 col-sm-offset-2"> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">BOOK EDIT</h3> </div> <div class="panel-body"> <form action="" method="post" class="form-horizontal"> {% csrf_token %} {% for foo in book %} <div class="form-group"> <label class="col-md-3 control-label" id="{{ foo.auto_id }}">{{ foo.label }}</label> <div class="col-md-9">{{ foo }}</div> </div> {% endfor %} <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <input type="submit" class="btn btn-info" value="提交"> </div> </div> </form> </div> </div> </div> </div> </div> </body> </html>
from django.forms import ModelForm from app01 import models class BookModelForm(ModelForm): class Meta: model = models.Book fields = "__all__" labels = { "name": "名字", "price": "价格", "publish": "出版社", "authors": "作者", } from django.forms import widgets as wid widgets = { "name": wid.TextInput(attrs={"class": "form-control"}), "price": wid.TextInput(attrs={"class": "form-control"}), "publish": wid.Select(attrs={"class": "form-control"}), "authors": wid.SelectMultiple(attrs={"class": "form-control"}), } def edit(request): book_id = request.GET.get("id") book_obj = models.Book.objects.filter(pk=book_id).first() if not book_obj: return HttpResponse("404 error.") if request.method == "GET": book = BookModelForm(instance=book_obj) return render(request, "edit.html", {"book": book}) else: book_obj = BookModelForm(request.POST, instance=book_obj) if book_obj.is_valid(): book_obj.save() return redirect("/book/")
说明: 1. 前端显示中文名也可以在model表中设置,如下: class Book(models.Model): name = models.CharField(max_length=32, verbose_name="书名") 2. 修改数据,提交数据时必须叫上instance参数,然后必须使用save提交到数据库
3、添加数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" type="text/css" href="/static/bootstrap3/css/bootstrap.min.css"> <script src="/static/bootstrap3/js/bootstrap.min.js"></script> <script src="/static/jquery-3.3.1.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-sm-8 col-sm-offset-2"> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">BOOK ADD</h3> </div> <div class="panel-body"> <form action="" method="post" class="form-horizontal" novalidate> {% csrf_token %} {% for foo in book %} <div class="form-group"> <label class="col-md-3 control-label" id="{{ foo.auto_id }}">{{ foo.label }}</label> <div class="col-md-9">{{ foo }}</div> </div> {% endfor %} <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <input type="submit" class="btn btn-info" value="提交"> </div> </div> </form> </div> </div> </div> </div> </div> </body> </html>
# 在BookModelForm类中添加错误提示信息 error_messages = { "name": {"required": "不能为空"}, "price": {"required": "不能为空"}, "publish": {"required": "不能为空"}, "authors": {"required": "不能为空"}, }
# 视图函数 def add(request): book = BookModelForm() if request.method == "POST": book_obj = BookModelForm(request.POST) if book_obj.is_valid(): book_obj.save() return redirect("/book") else: return HttpResponse(str(book_obj.errors)) return render(request, "add.html", {"book": book})

浙公网安备 33010602011771号