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>
前端书籍表单,book.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>
# 前端edit.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>
# 前端edit.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})

 

posted @ 2019-05-10 10:12  yw_sun  阅读(99)  评论(0)    收藏  举报