zoukankan      html  css  js  c++  java
  • Django ModelForm组件

    一、创建ModelForm

    from django.forms import ModelForm
    from appxx import models
    from django.forms import widgets as wdt  # 因为重名,所以起个别名
    #定义一个类,比如BookForm,这个类要继承ModelForm,在这个类中再写一个原类Meta(规定写法,注意首字母是大写的)
    #在这个原类中,有以下属性(部分):
    class BookForm(ModelForm):
        class Meta:
            model = models.Book  # 对应的Model中的类
            fields = "__all__" # 字段,如果是__all__,就表示列出所有的字段,或者使用列表列出想要的字段
            exclude = None  # 排除的字段
            # error_messages用法
            error_messages = {
                "title": {"required": "书名不能为空"},
                "price": {"required": "售价不能为空"},
            }
            # widgets用法,比如把输入用户名的input框给为Textarea
            widgets = {
                "name": wdt.Textarea(attrs={"class": "c1"})  # 还可以自定义属性
            }
            #labels,自定义在前端显示的名字
            labels= {
                "title": "书名",
                "price": "售价",
            }

    然后在 url 对应的视图函数中实例化这个类,把这个对象传给前端:

    def add_book(request):
        form = forms.BookForm()
        return render(request, "add_book.html", {"form": form})

    然后在前端像Form组件那样渲染页面,具体点击这里

    二、添加数据

    保存数据的时候,不用挨个取数据了,只需要 save 一下即可。

    from django.shortcuts import render,redirect
    from appxx import models
    from appxx import forms
    
    
    def add_book(request):
        if request.method == "POST":
            form = forms.BookForm(request.POST)
            if form.is_valid():
                form.save()
                return redirect("/book/")
        form = forms.BookForm()
        return render(request, "add_book.html", {"form": form})

    三、编辑数据

    如果不使用 ModelForm,编辑的时候得显示之前的数据,还得挨个取一遍值;如果使用 ModelForm,只需要加一个instance=obj(obj是要修改的数据库的一条数据的对象)就可以得到同样的效果。
    保存的时候要注意,一定要注意有这个对象(instance=obj),否则不知道更新哪一个数据。

    from django.shortcuts import render,redirect
    from appxx import models
    from appxx import forms
    
    
    def edit_book(request, edit_book_id):
        edit_book= models.Book.objects.filter(id=edit_book_id).first()
        if request.method == "POST":
            form = forms.BookForm(request.POST, instance=edit_book)
            if form.is_valid():
                form.save()
                return redirect("/book/")
        form = forms.BookForm(instance=edit_book)
        return render(request, "edit_book.html", {"form": form})

    总结: 从上边可以看到 ModelForm 用起来是非常方便的,比如增加修改之类的操作。但是也带来额外不好的地方,model和form之间耦合了。如果不耦合的话,form.save()方法也无法直接提交保存。 但是耦合的话使用场景通常局限用于小程序,写大程序就最好不用了。

    四、完整示例代码

    项目结构

    urls.py

    from django.conf.urls import url
    from django.contrib import admin
    from appxx import views
    
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r"^book/$", views.book),
        url(r"^book/add/", views.add_book),
        url(r"^book/edit/(d+)/", views.edit_book),
    ]

    views.py

    from django.shortcuts import render,redirect
    from appxx import models
    from appxx import forms
    
    
    def book(request):
        book_list = models.Book.objects.all()
        return render(request, "book.html", {"book_list": book_list})
    
    
    def add_book(request):
        if request.method == "POST":
            form = forms.BookForm(request.POST)
            if form.is_valid():
                form.save()
                return redirect("/book/")
        form = forms.BookForm()
        return render(request, "add_book.html", {"form": form})
    
    
    def edit_book(request, edit_book_id):
        edit_book= models.Book.objects.filter(id=edit_book_id).first()
        if request.method == "POST":
            form = forms.BookForm(request.POST, instance=edit_book)
            if form.is_valid():
                form.save()
                return redirect("/book/")
        form = forms.BookForm(instance=edit_book)
        return render(request, "edit_book.html", {"form": form})

    models.py

    from django.db import models
    
    
    class Book(models.Model):
        id = models.AutoField(primary_key=True)
        title = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        publish_date = models.DateField()
        publisher = models.ForeignKey(to="Publisher")
        authors = models.ManyToManyField(to="Author")
    
        def __str__(self):
            return self.title
    
    
    class Publisher(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
    
        def __str__(self):
            return self.name
    
    
    class Author(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
    
        def __str__(self):
            return self.name

    forms.py

    from django.forms import ModelForm
    from appxx import models
    from django.forms import widgets as wdt
    
    
    class BookForm(ModelForm):
        class Meta:
            model = models.Book
            fields = "__all__"
            labels = {
                "title": "书名",
                "price": "售价",
                "publish_date": "出版日期",
                "publisher": "出版社",
                "authors": "作者"
            }
            widgets = {
                "title": wdt.TextInput(attrs={"class": "form-control"}),
                "price": wdt.TextInput(attrs={"class": "form-control"}),
                "publish_date": wdt.TextInput(attrs={"class": "form-control", "type": "date"}),
                "publisher": wdt.Select(attrs={"class": "form-control"}),
                "authors": wdt.SelectMultiple(attrs={"class": "form-control"}),
    
            }
            error_messages = {
                "title": {"required": "书名不能为空"},
                "price": {"required": "售价不能为空"},
                "publish_date": {"required": "出版日期不能为空"},
                "publisher": {"required": "出版社不能为空"},
                "authors": {"required": "作者不能为空"},
            }

    book.html

    <!DOCTYPE html>
    <html lang="zh-cn">
    <head>
        <meta charset="UTF-8">
        <title>展示书籍</title>
        <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <span><a class="btn btn-primary" href="/book/add/">添加</a></span>
                <table class="table table-striped table-bordered">
                    <thead>
                    <tr>
                        <th>序号</th>
                        <th>书名</th>
                        <th>售价</th>
                        <th>出版日期</th>
                        <th>出版社</th>
                        <th>作者</th>
                        <th>操作</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for book in book_list %}
                        <tr>
                            <td>{{ forloop.counter }}</td>
                            <td>{{ book.title }}</td>
                            <td>{{ book.price }}</td>
                            <td>{{ book.publish_date }}</td>
                            <td>{{ book.publisher.name }}</td>
                            <td>
                                {% for author in book.authors.all %}
                                    {{ author.name }}
                                {% endfor %}
                            </td>
                            <td>
                                <span><a class="btn btn-warning" href="/book/edit/{{ book.pk }}/">编辑</a></span>
                                <span><a class="btn btn-danger" href="">删除</a></span>
                            </td>
                        </tr>
                    {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
    </body>
    </html>
    View Code

    add_book.html和edit_book.html(两个页面代码一样) 

    <!DOCTYPE html>
    <html lang="zh-cn">
    <head>
        <meta charset="UTF-8">
        <title>添加书籍</title>
        <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
        <style>
            .panel-title {
                font-weight: bolder;
            }
    
            .panel {
                margin-top: 30px;
            }
        </style>
    </head>
    <body>
    <div class="container">
        <div class="row">
            {# panel开始 #}
            <div class="panel panel-danger col-sm-6 col-md-6 col-sm-offset-3 col-md-offset-3">
                <div class="panel-heading">
                    <h3 class="panel-title">添加书籍</h3>
                </div>
                {# panel-body开始 #}
                <div class="panel-body">
                    {# form开始 #}
                    <form class="form-horizontal" action="" method="post" novalidate>
                        {% csrf_token %}
                        <div class="form-group">
                            <label class="col-md-2 control-label"
                                   for="{{ form.title.id_for_label }}">{{ form.title.label }}</label>
                            <div class="col-md-10">
                                {{ form.title }}
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-md-2 control-label"
                                   for="{{ form.price.id_for_label }}">{{ form.price.label }}</label>
                            <div class="col-md-10">
                                {{ form.price }}
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-md-2 control-label"
                                   for="{{ form.publish_date.id_for_label }}">{{ form.publish_date.label }}</label>
                            <div class="col-md-10">
                                {{ form.publish_date }}
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-md-2 control-label"
                                   for="{{ form.publisher.id_for_label }}">{{ form.publisher.label }}</label>
                            <div class="col-md-10">
                                {{ form.publisher }}
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-md-2 control-label"
                                   for="{{ form.authors.id_for_label }}">{{ form.authors.label }}</label>
                            <div class="col-md-10">
                                {{ form.authors }}
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-md-offset-2 col-md-10">
                                <button type="submit" class="btn btn-success">提交</button>
                                <a class="btn btn-warning pull-right" href="/book/">取消</a>
                            </div>
                        </div>
                    </form>
                    {# form结束 #}
                </div>
                {# panel-body结束 #}
            </div>
            {# panel结束 #}
        </div>
    </div>
    </body>
    </html>
    View Code
  • 相关阅读:
    希腊字母写法
    The ASP.NET MVC request processing line
    lambda aggregation
    UVA 10763 Foreign Exchange
    UVA 10624 Super Number
    UVA 10041 Vito's Family
    UVA 10340 All in All
    UVA 10026 Shoemaker's Problem
    HDU 3683 Gomoku
    UVA 11210 Chinese Mahjong
  • 原文地址:https://www.cnblogs.com/believepd/p/10067679.html
Copyright © 2011-2022 走看看