python测试开发django-109.ModelForm模型表单的使用

前言

django的表单有2种:forms.Form 和 forms.ModelForm。ModelForm顾名思义是将模型和表单结合起来,这个功能是非常强大的!

Model模型

Model模型设计如下

from django.db import models
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
# Create your models here.

class Detail(models.Model):
    user = models.CharField(max_length=30, blank=True, null=True)
    age = models.IntegerField(blank=True, null=True)
    email = models.EmailField(blank=True, null=True)
    city = models.CharField(max_length=30, blank=True, null=True)
    GENDER_CHOICES = (
        ('男', '男'),
        ('女', '女'),
    )
    gender = models.CharField(
        max_length=30,
        choices=GENDER_CHOICES
    )
    fancy = models.CharField(max_length=30, blank=True, null=True)
    comment = models.TextField()
    birth = models.DateTimeField()

ModelForm模型表单

在视图中,定义一个类DetailModelForm,这个类要继承forms.ModelForm,在这个类中再写一个原类Meta

from django.forms import models as form_model
from django.forms import widgets
from .models import Detail
from django.views import View
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/


class DetailModelForm(forms.ModelForm):
    """模型表单"""

    class Meta:
        model = Detail        # 对应的Model中的类
        # fields = "__all__"    # 字段,如果是__all__,就是表示列出所有的字段
        fields = ["user", "age", "gender", "email", "city", "birth", "comment", "fancy"]
        exclude = None        # 排除的字段
        help_texts = None     # 帮助提示信息
        error_messages = {
            'user': {'required': 'user不能为空',
                     'min_length': 'user不能少于3个字符',
                     'max_length': 'user不能超过12个字符'},
            'age': {'min_value': '不能小于0', },
            'gender': {'invalid': '输入不合法'},
            'email': {'invalid': '输入不合法'},
            'city': {'invalid': '输入不合法'},
        }
        # widgets 用法, 比如把输入用户名的input框给为Textarea
        widgets = {
            "user": widgets.TextInput(attrs={"class": "xx"}),
            "age": widgets.NumberInput,
            "gender": widgets.RadioSelect(choices=[
                                                    (1, '男'),
                                                    (2, '女')
                                                ]),
            "email": widgets.EmailInput,
            "city": widgets.Select(choices=[
                                                ("北京", "北京"),
                                                ("上海", "上海"),
                                                ("深圳", "深圳"),
                                                ("杭州", "杭州"),
                                            ]),

            "birth": widgets.DateInput(attrs={'type': 'date', 'value': '2021-01-01'}),
            "comment": widgets.Textarea,
            # 多选checkbox
            "fancy": widgets.CheckboxSelectMultiple(
                choices=((1, 'Python'), (2, 'Selenium'), (3, "Appium"))
            ),

        }
        # labels,自定义在前端显示的名字
        labels = {
            "user": "姓名",
            "age": "年龄",
            "gender": "性别",
            "email": "邮箱",
            "city": "城市",
            "birth": "出生年月",
            "comment": "评论",
            "fancy": "爱好"
        }

在视图中可以直接通过form_obj.save()保存数据,非常方便。

from django.views import View
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

class DetailModelView(View):

    def get(self, request):
        form_obj = DetailModelForm()
        return render(request, "detail.html", locals())

    def post(self, request):
        form_obj = DetailModelForm(request.POST)
        if form_obj.is_valid():
            # data = form_obj.cleaned_data()
            form_obj.save()
            msg = "保存成功"
            return render(request, "detail.html", locals())

        else:
            # 全局钩子自定义错误提示获取
            print(form_obj.errors.get('__all__')[0])
            error_msg = form_obj.errors.get('__all__')[0]

        return render(request, "detail.html", locals())

模板与显示效果

detail.html模板内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>详情页面</title>
    <style>
        ul li{
            list-style: none;
        }
    </style>
</head>
<body>
<form action="" method="POST" id="detail-form" >
    {% csrf_token %}
    {% for field in form_obj %}
        {% if field.label == "性别" %}
            {{ field.label_tag }}
            {{ field.1 }} {{ field.2 }}

        {% elif field.label == "爱好" %}
            {{ field.label_tag }}
            {% for f in field %}
                 {{ f }}
            {% endfor %}

        {% else %}
            <p>
            {{ field.label_tag }}
            {{ field }}
            {{ field.errors }}
        </p>

        {% endif %}

    {% endfor %}
    <p>
        {% if msg %}
            {{ msg }}

        {% endif %}

    </p>
    <p>
        <input type="submit" value="提交" >
    </p>
</form>
</body>
</html>

页面显示效果

Meta中属性

属性 说明
model 必须项,对应的Model中的类
fields 字段,如果是__all__,就是表示列出所有的字段
exclude 排除的字段
labels 提示信息
help_texts 帮助提示信息
widgets 自定义插件
error_messages 自定义错误信息
field_classes 将模型的字段类型查询定义为表单字段类型,默认情况模型字段自动转表单字段类型
posted @ 2021-07-14 23:18  上海-悠悠  阅读(430)  评论(0编辑  收藏  举报