django forms组件,model from组件

django forms组件,model from组件

内容概要

forms组件简单使用

form组件渲染标签

forms组件校验补充

forms组件参数补充

forms组件源码剖析

modelfrom组件

forms组件

小需求:获取用户数据并发送给后端校验 后端返回不符合校验规则的提示信息

form组件

​ 1.自动校验数据

​ 2.自动生成标签

​ 3.自动展示信息

from django import forms


class MyForm(forms.Form):
    username = forms.CharField(min_length=3, max_length=8)  # username字段最少三个字符最大八个字符
    age = forms.IntegerField(min_value=0, max_value=200)  # 年龄最小0 最大200
    email = forms.EmailField()  # 必须符合邮箱格式

校验数据功能

form_obj = views.MyForm({'username':'jason','age':18,'email':'123'})
form_obj.is_valid()  # 1.判断数据是否全部符合要求
False  # 只要有一个不符合结果都是False
form_obj.cleaned_data  # 2.获取符合校验条件的数据
{'username': 'jason', 'age': 18}
form_obj.errors  # 3.获取不符合校验规则的数据及原因
{'email': ['Enter a valid email address.']}

1.只校验类中定义好的字段对应的数据 多传的根本不做任何操作

2.默认情况下类中定义好的字段都是必填的

forms组件渲染标签

<p>forms组件渲染标签的方式1(封装程度过高 扩展性差 主要用于本地测试):</p>
    {#    {{ form_obj.as_p }}#}
    {#    {{ form_obj.as_ul }}#}
    {#    {{ form_obj.as_table }}#}
<p>forms组件渲染标签的方式2(封装程度过低 扩展性高 编写麻烦)</p>
    {#    {{ form_obj.username.label }}#}
    {#    {{ form_obj.username }}#}
    {#    {{ form_obj.age.label }}#}
    {#    {{ form_obj.age }}#}
    {#    {{ form_obj.email.label }}#}
    {#    {{ form_obj.email }}#}
<p>forms组件渲染标签的方式3(封装程度较高 扩展性高 编写简单 推荐使用)</p>
    {#    {% for form in form_obj %}#}
    {#        <p>#}
    {#            {{ form.label }}#}
    {#            {{ form }}#}
    {#        </p>#}
    {#    {% endfor %}#}

注意事项:forms组件负责获取用户数据的标签 也就意味着form标签与按钮都需要自己写

前端的校验是弱不禁风的 最终都需要后端来校验 所以我们在使用forms组件的时候可用直接取消前端帮我们的校验

<form action="" method="post" novalidate>

forms组件展示信息

后端不同请求返回的forms对象一定要是相同的变量名
def ab_forms_func(request):
    # 1.产生一个空对象
    form_obj = MyForm()
    if request.method == 'POST':
        form_obj = MyForm(request.POST)  # request.POST可以看成是一个字典 直接传给forms类校验 字典中无论有多少键值对都没关系 之在乎类中编写的
        if form_obj.is_valid():  # 校验数据是否合法
            print(form_obj.cleaned_data)
        else:
            print(form_obj.errors)
    # 2.将该对象传递给html文件
    return render(request, 'formsPage.html', locals())

{% for form in form_obj %}
            <p>
                {{ form.label }}
                {{ form }}
                <span>{{ form.errors.0 }}</span>
            </p>
{% endfor %}
针对错误信息的提示可以修改成各国语言

方式1:自定义错误内容

给字段对象添加errors_messages参数

username = forms.CharField(min_length=3, max_length=8, label='用户名',
                           error_messages={
                               'min_length': '用户名最少三个字符',
                               'max_length': '用户名最多八个字符',
                               'required': '用户名不能为空'
                           }
                          )

image

方式2:修改系统语言环境

from django.conf import global_settings  django内部真正的配置文件


LANGUAGE_CODE = 'zh-hans'



LANGUAGE_CODE = 'en-us'

# Languages we provide translations for, out of the box.
LANGUAGES = [
    ('af', gettext_noop('Afrikaans')),
    ('ar', gettext_noop('Arabic')),
    ('ast', gettext_noop('Asturian')),
    ('az', gettext_noop('Azerbaijani')),
    ('bg', gettext_noop('Bulgarian')),
    ('be', gettext_noop('Belarusian')),
    ('bn', gettext_noop('Bengali')),
    ('br', gettext_noop('Breton')),
    ('bs', gettext_noop('Bosnian')),
    ('ca', gettext_noop('Catalan')),
    ('cs', gettext_noop('Czech')),
    ('cy', gettext_noop('Welsh')),
    ('da', gettext_noop('Danish')),
    ('de', gettext_noop('German')),
    ('dsb', gettext_noop('Lower Sorbian')),
    ('el', gettext_noop('Greek')),
    ('en', gettext_noop('English')),
    ('en-au', gettext_noop('Australian English')),
    ('en-gb', gettext_noop('British English')),
    ('eo', gettext_noop('Esperanto')),
    ('es', gettext_noop('Spanish')),
    ('es-ar', gettext_noop('Argentinian Spanish')),
    ('es-co', gettext_noop('Colombian Spanish')),
    ('es-mx', gettext_noop('Mexican Spanish')),
    ('es-ni', gettext_noop('Nicaraguan Spanish')),
    ('es-ve', gettext_noop('Venezuelan Spanish')),
    ('et', gettext_noop('Estonian')),
    ('eu', gettext_noop('Basque')),
    ('fa', gettext_noop('Persian')),
    ('fi', gettext_noop('Finnish')),
    ('fr', gettext_noop('French')),
    ('fy', gettext_noop('Frisian')),
    ('ga', gettext_noop('Irish')),
    ('gd', gettext_noop('Scottish Gaelic')),
    ('gl', gettext_noop('Galician')),
    ('he', gettext_noop('Hebrew')),
    ('hi', gettext_noop('Hindi')),
    ('hr', gettext_noop('Croatian')),
    ('hsb', gettext_noop('Upper Sorbian')),
    ('hu', gettext_noop('Hungarian')),
    ('hy', gettext_noop('Armenian')),
    ('ia', gettext_noop('Interlingua')),
    ('id', gettext_noop('Indonesian')),
    ('io', gettext_noop('Ido')),
    ('is', gettext_noop('Icelandic')),
    ('it', gettext_noop('Italian')),
    ('ja', gettext_noop('Japanese')),
    ('ka', gettext_noop('Georgian')),
    ('kab', gettext_noop('Kabyle')),
    ('kk', gettext_noop('Kazakh')),
    ('km', gettext_noop('Khmer')),
    ('kn', gettext_noop('Kannada')),
    ('ko', gettext_noop('Korean')),
    ('lb', gettext_noop('Luxembourgish')),
    ('lt', gettext_noop('Lithuanian')),
    ('lv', gettext_noop('Latvian')),
    ('mk', gettext_noop('Macedonian')),
    ('ml', gettext_noop('Malayalam')),
    ('mn', gettext_noop('Mongolian')),
    ('mr', gettext_noop('Marathi')),
    ('my', gettext_noop('Burmese')),
    ('nb', gettext_noop('Norwegian Bokmål')),
    ('ne', gettext_noop('Nepali')),
    ('nl', gettext_noop('Dutch')),
    ('nn', gettext_noop('Norwegian Nynorsk')),
    ('os', gettext_noop('Ossetic')),
    ('pa', gettext_noop('Punjabi')),
    ('pl', gettext_noop('Polish')),
    ('pt', gettext_noop('Portuguese')),
    ('pt-br', gettext_noop('Brazilian Portuguese')),
    ('ro', gettext_noop('Romanian')),
    ('ru', gettext_noop('Russian')),
    ('sk', gettext_noop('Slovak')),
    ('sl', gettext_noop('Slovenian')),
    ('sq', gettext_noop('Albanian')),
    ('sr', gettext_noop('Serbian')),
    ('sr-latn', gettext_noop('Serbian Latin')),
    ('sv', gettext_noop('Swedish')),
    ('sw', gettext_noop('Swahili')),
    ('ta', gettext_noop('Tamil')),
    ('te', gettext_noop('Telugu')),
    ('th', gettext_noop('Thai')),
    ('tr', gettext_noop('Turkish')),
    ('tt', gettext_noop('Tatar')),
    ('udm', gettext_noop('Udmurt')),
    ('uk', gettext_noop('Ukrainian')),
    ('ur', gettext_noop('Urdu')),
    ('vi', gettext_noop('Vietnamese')),
    ('zh-hans', gettext_noop('Simplified Chinese')),
    ('zh-hant', gettext_noop('Traditional Chinese')),
]

forms组件校验补充

forms组件针对字段数据的校验 提供了三种类型的校验方式(可用一起使用)

第一种类型:直接填写参数 max_length

第二种类型:使用正则表达式 validators

第三种类型:钩子函数 编写代码自定义校验规则

钩子函数》》》校验的最后一环 是再字段所有的校验参数之后触发

class Myform(forms.Form):
    username = forms.CharField(min_length=3, max_length=8, label='用户名'
                               , error_messages={
            'max_length': '超出长度了',
            'min_length': '细狗',
            'required': '用户名名内容不能为空'
        })
    pwd = forms.CharField(max_length=32)
    age = forms.IntegerField(max_value=200, min_value=0)
    email = forms.EmailField(label='邮箱')

    # 局部钩子
    def clean_username(self):
        username = self.cleaned_data.get('username')
        if username == 'ikun':
            self.add_error('username', '小黑子')
        return username  # 使用完毕后返回回去
    # 全局钩子
    def clean(self):
        pwd = self.cleaned_data.get('pwd')
        if pwd == '123':
            self.add_error('pwd', '密码太简单了')
        return self.cleaned_data  # 使用完毕后返回回去

image

forms组件参数补充

min_length			最小字符
max_length			最大字符
min_value			最小值
max_value			最大值
label				字段注释
error_messages		错误提示
validators			正则校验器
initial				默认值
required			是否必填
widget				控制标签的各项属性
widget=forms.widgets.PasswordInput(attrs={'class': 'form-control', 'username': 'jason'})

forms组件源码剖析

切入口:form_obj.is_valued()

@property
def errors(self):
    """Return an ErrorDict for the data provided for the form."""
    if self._errors is None:  # 这个里self._errors刚开始是None所有向下走
        self.full_clean()  # 到这里
        return self._errors

def is_valid(self):
    """Return True if the form has no errors, or False otherwise."""
    # self.is_bound就是传入的数据没什么好看的,然后看self.errors再上面刚好找到是一个属性值方法
    return self.is_bound and not self.errors
def full_clean(self):
    """
        Clean all of self.data and populate self._errors and self.cleaned_data.
        """
    self._errors = ErrorDict()  # 生成一个错误字典看见Dict那么她就跟字典有关系
    if not self.is_bound:  # Stop further processing.  判断有没有传入数据
        return
    self.cleaned_data = {}  # 创建一个存放干净数据的zi'di'a
    # If the form is permitted to be empty, and none of the form data has
    # changed from the initial data, short circuit any validation.
    if self.empty_permitted and not self.has_changed():
        return

    self._clean_fields() # 清洗字段数据,局部钩子触发
    self._clean_form()  # 全局钩子
    self._post_clean()  # 暂时无用为以后提前写下的方法

model form组件

我们学习校验组件的目的 绝大部分是为了数据录入数据库之前各项审核

forms组件使用的时候需要对照模型类编写代码 不够方便

forms组件的强化版 更好用更简便更方便

from django import forms
from User import models


class MyModelForm(forms.ModelForm):
    class Meta:
        model = models.Book
        fields = '__all__'
        labels = {
            'title': '书名1',
            'price': '价格'
        }


def model_form(request):
    book_obj = models.Book.objects.filter(pk=5).first()
    myobj = MyModelForm(initial=book_obj)
    if request.method == 'POST':

        myobj = MyModelForm(request.POST,instance=book_obj)  # instance更快速的修改数据
        myobj.save()  # instance参数就算修改,没有就是新增数据
        print(myobj.is_valid())
        print(myobj.cleaned_data)
    return render(request, 'formPage.html', locals())

image

posted @ 2022-12-25 20:08  clever-cat  阅读(31)  评论(0编辑  收藏  举报