Bootstrap

Django组件之modelform

前言

经历了前面的纯手写我的form逻辑,以及我们的Django的form组件,终于来到了ModelForm组件了。

ModelForm是我们form与model的结合很是强大。

ModelForm:我直接写在了views.py里面,这是个不好的习惯知道吧,我是为了方便:
在这里面class Meta: 的Meta大写的请注意。

class BookForm(ModelForm):
    class Meta:
        model = Book#对应的Model中的类
        fields = "__all__" # 显示所有字段

然后我们的视图:

# 添加页面
def add_book(request):
    if request.method == 'POST':
        form = BookForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/book/')
        else:
            print('error', form.errors)
            return render(request, 'add_book.html', locals())
    # 这是访问添加页面,不涉及表单数据提交
    form = BookForm()
    return render(request, 'add_book.html', locals())

html:

            <form action="" method="post" novalidate>
                {% csrf_token %}
                {% for f in form %}
                    <p>
                        {{ f.label }}
                        {{ f }}
                    </p>
                {% endfor %}
                <input type="submit" value="提交">
            </form>

看看实现的效果:
在这里插入图片描述
写了少量代码即可出现极好效果是真的快乐哦,我这里要之所以label名字显示中文是因为我在model中设置了 title = models.CharField(max_length=32, verbose_name=‘书名’) # 书名 verbose_name这个属性。不然是显示为你的字段名字的。

class Meta常用的参数
model = models.Book  # 对应的Model中的类
fields = "__all__"  # 字段,如果是__all__,就是表示列出所有的字段
exclude = None  # 排除的字段
labels = None  # 字段显示信息(这个级别高于verbose_name的)
help_texts = None  # 帮助提示信息
widgets = None  # 自定义插件
error_messages = None  # 自定义错误信息

#widgets用法,比如把输入用户名的input框给为Textarea
        #首先得导入模块
        from django.forms import widgets as wid #因为重名,所以起个别名
        widgets = {
        "name":wid.Textarea(attrs={"class":"c1"}) #还可以自定义属性
        }

再看看我们编辑数据的:
edit_book:

def edit_book(request, id):
    # 获取当前需要编辑数据
    book_obj = Book.objects.filter(id=id).first()
    # 提交表单数据
    if request.method == 'POST':
        # instancej加上去才是表示更新数据,不然默认是创建一条数据
        form = BookForm(request.POST, instance=book_obj)
        if form.is_valid():
            form.save()
        return redirect('/book/')
    form = BookForm(instance=book_obj)
    return render(request, 'edit_book.html', locals())

在这里插入图片描述
原先的数据直接展现在里面,是真的方便。

有人会说样式呢。也可以解决,还有信息验证的错误提示呢。再顺便吧静态的整理一番。

import re

from .models import *
from django.forms import ModelForm
from django.shortcuts import render, redirect
from django.forms import widgets as wid


# Create your views here.



class BookForm(ModelForm):
    class Meta:
        model = Book
        fields = "__all__"
        widgets = {
            'title': wid.TextInput(attrs={'class': 'form-control'}),
            'price': wid.TextInput(attrs={'class': 'form-control'}),
            'date': wid.TextInput(attrs={'class': 'form-control'}),
            'title': wid.TextInput(attrs={'class': 'form-control'}),
            'publishs': wid.Select(attrs={'class': 'form-control'}),
            'authors': wid.SelectMultiple(attrs={'class': 'form-control'})
        }
        error_messages = {
            'title': {'required': '书名不能为空'},
            'price': {'required': '价格不能为空'},
            'date': {'required': '日期不能为空'},
        }
        labels = {
            'title': '书籍名'
        }


# 查看 8034442
def books(request):
    book_obj = Book.objects.all()
    return render(request, 'book.html', locals())


# 添加页面
def add_book(request):
    if request.method == 'POST':
        form = BookForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/book/')
        else:
            print('error', form.errors)
            return render(request, 'add_book.html', locals())
    # 这是访问添加页面,不涉及表单数据提交
    form = BookForm()
    return render(request, 'add_book.html', locals())


def edit_book(request, id):
    # 获取当前需要编辑数据
    book_obj = Book.objects.filter(id=id).first()
    # 提交表单数据
    if request.method == 'POST':
        # instancej加上去才是表示更新数据,不然默认是创建一条数据
        form = BookForm(request.POST, instance=book_obj)
        if form.is_valid():
            form.save()
        return redirect('/book/')
    form = BookForm(instance=book_obj)
    return render(request, 'edit_book.html', locals())

html的代码:

创建一个inl_book:

<div class="container">
    <div class="row">
        <div class="col-md-4">sss</div>
        <div class="col-md-4">
            <form action="" method="post" novalidate>
                {% csrf_token %}
                {% for f in form %}
                    <p>
                        {{ f.label }}
                        {{ f }}
                    </p>
                    {% if f.errors %}
                        <h6 style="color: red; list-style: none">
                            {{ f.errors }}
                        </h6>
                    {% endif %}
                {% endfor %}
                <input type="submit" value="提交">
            </form>
        </div>
        <div class="col-md-4">sss</div>
    </div>
</div>

我们再把add_book.html和edit_book.html修改一下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <title>添加书籍</title>
</head>
<body>
{% include 'inl_book.html' %}
</body>
</html>

编辑html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <title>编辑书籍 </title>
</head>
<body>
<h4>编辑书籍</h4>
{% include 'inl_book.html' %}
</body>
</html>

来看看我们的效果吧:
在这里插入图片描述
这里日期没有修改好,利用我们的样式定制自己修改一下吧!

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;