zoukankan      html  css  js  c++  java
  • Django 的 model form 组件

    Django 的 model form 组件

    Model Form 组件的由来

    之前介绍过 Django 的 Form 组件(Django的Form表单)使用方法,Form 组件能够帮我们做三件事:

    1. 生成页面可用的HTML标签

    2. 对用户提交的数据进行校验

    3. 保留上次输入内容

    我们发现,form 类中的字段和 model 类中的字段及其相似,但 form 表单和 model 类并没有什么关系。对于每一个 model 类,我们都需要为其创建一个对应的 form 类,还要根据该 model 类定义校验。

    这种方式增添了很多重复劳动,所以出现了 model form 组件,它可以优雅地生成 form 类,并且在校验方面更简单。

    创建 model form

    要用到的 model 类有:

    from django.db import models
    
    
    # Create your models here.
    class Book(models.Model):
        title = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name="价格")
        date = models.DateField()
        publish = models.ForeignKey(to="Publish")
        authors = models.ManyToManyField(to="Author")
    
        def __str__(self):
            return self.title
    
    
    class Publish(models.Model):
        name = models.CharField(max_length=32)
    
        def __str__(self):
            return self.name
    
    
    class Author(models.Model):
        name = models.CharField(max_length=32)
    
        def __str__(self):
            return self.name
    
    

    直接在视图层中创建 model form

    # views.py
    
    # 导入 ModelForm
    from django.forms import ModelForm
    from django.forms import widgets as wid    # 避免重名
    
    
    class Book(ModelForm):
        class Meta:
            # 对应的Model类
            model = models.Book
            # 字段,all表示列出所有字段
            fields = "__all__"
    
            # labels 自定义显示的名字,
            labels = {
                "title": "书名",
                "publish": "出版社",
                "date": "出版日期",
                "authors": "作者",
            }
    		
    		# error_messages用法:
            error_messages = {
                'title': {'required': "书名不能为空", },
                'date': {'required': "出版日期不能为空", },
            }
    		
            widgets = {
                "title": wid.TextInput(attrs={"class": "form-control"}),
                "date": wid.TextInput(attrs={"type": "date"})
            }
    
    

    展示数据

    视图函数中的使用

    在视图函数中将该类实例化并传到前端。

    def book(request):
        book_list = models.Book.objects.all()
        # book = Book()
        return render(request, 'book.html', locals())
    

    模板中的使用

    前端只需要 {{book_list.as_p }} 一下,所有的字段就都出来了,可以用 as_p 显示全部,也可以通过 for 循环这 book_list ,拿到的是一个个 input 框,这种方法支持加 class 样式类。

    
    <table border="1">
        {% for book in book_list %}
           <tr>
               <td>{{ book.title }}</td>
               <td>{{ book.price }}</td>
               <td>{{ book.date|date:"Y-m-d" }}</td>
               <td>{{ book.publish.name }}</td>
               <td>
                   {% for author in book.authors.all %}
                       {{ author.name }}
                   {% endfor %}
    
               </td>
               <td><a href="/book/edit/{{book.pk}}"><button>编辑</button></a></td>
           </tr>
        {% endfor %}
    
    </table>
    

    在后台给在前端显示的字段加属性。

    widgets = {
    	"title": wid.TextInput(attrs={"class": "form-control"}),
    	"date": wid.TextInput(attrs={"type": "date"})
    }
    

    添加数据

    视图函数中的使用

    使用 model form 类在添加时变的十分简单,通过 request.POST 创建一个 Book 对象,判断其是否通过验证,如果通过验证,只需简单的 book.save() 就能保存到数据库中。

    def add_book(request):
        if request.method == "POST":
            book = Book(request.POST)
            if book.is_valid():
                book.save()
                return redirect('/book/')
        book = Book()
        return render(request, 'add.html', locals())
    

    模板中的使用

    模板中的使用与上面的相同。

    <form action="" method="post" novalidate>
         {% csrf_token %}
    {#    一个as_p就能将所有HTML标签自动加上#}
         {{ book.as_p }}
    
        <input type="submit" value="提交">
    </form>
    

    编辑数据

    视图函数中的使用

    在编辑功能中我们希望编辑页面能显示原来的数据,用 model form 类很容易就能实现。

    根据要编辑书籍的 id 值取出相应的书籍对象并加上 instance 字段用该对象创建 Book 实例对象,即可实现。

    def edit_book(request, id):
        book_obj = models.Book.objects.filter(pk=id).first()
        if not book_obj:
            return HttpResponse("无该书籍")
        if request.method == "POST":
            book = Book(request.POST, instance=book_obj)
            if book.is_valid():
                book.save()
                return redirect('/book/')
        book = Book(instance=book_obj)
        return render(request, 'edit.html', locals())
    
    

    模板中的使用

    模板中的使用与上面的相同。

    <form action="" method="post" novalidate>
         {% csrf_token %}
    {#    一个as_p就能将所有HTML标签自动加上#}
         {{ book.as_p }}
    
        <input type="submit" value="提交">
    </form>
    

    GitHub 地址:https://github.com/protea-ban/oldboy/tree/master/9day84

  • 相关阅读:
    【转载】Sqlserver存储过程中使用Select和Set给变量赋值
    【转载】腾讯云如何将一个域名解析到另一个域名上
    【转载】Sqlserver限制最大可使用内存
    【转载】 腾讯云通过设置安全组禁止某些IP访问你的服务器
    【转载】 C#使用Select方法快速获取List集合集合中某个属性的所有值集合
    【转载】哪些域名后缀可在工信部进行备案操作
    【转载】 C#使用string.Join快速用特定字符串串联起数组
    【转载】Sqlserver使用Convert函数进行数据类型转换
    【转载】Sqlserver根据生日计算年龄
    【转载】 腾讯云硬盘不够用,如何对硬盘进行扩容
  • 原文地址:https://www.cnblogs.com/banshaohuan/p/9890414.html
Copyright © 2011-2022 走看看