zoukankan      html  css  js  c++  java
  • 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 将模型的字段类型查询定义为表单字段类型,默认情况模型字段自动转表单字段类型
  • 相关阅读:
    开放API接口安全处理!
    ant笔记
    并发调试
    IDEA 设置(中文乱码、svn、热部署、ideolog 、Jrebel )
    win10家庭版升级专业版
    org.json package
    'root'@'localhost'不能登录问题
    javascript之DOM选择符
    javascript之DOM(四其他类型)
    javascript之DOM(三Element类型)
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/15013472.html
Copyright © 2011-2022 走看看