## django forms组件,model from组件 ## 内容概要 forms组件简单使用 form组件渲染标签 forms组件校验补充 forms组件参数补充 forms组件源码剖析 modelfrom组件 ## forms组件 小需求:获取用户数据并发送给后端校验 后端返回不符合校验规则的提示信息 form组件 1.自动校验数据 2.自动生成标签 3.自动展示信息 ```python 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() # 必须符合邮箱格式 ``` 校验数据功能 ```python 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组件渲染标签 ```python forms组件渲染标签的方式1(封装程度过高 扩展性差 主要用于本地测试): {# {{ form_obj.as_p }}#} {# {{ form_obj.as_ul }}#} {# {{ form_obj.as_table }}#} forms组件渲染标签的方式2(封装程度过低 扩展性高 编写麻烦) {# {{ form_obj.username.label }}#} {# {{ form_obj.username }}#} {# {{ form_obj.age.label }}#} {# {{ form_obj.age }}#} {# {{ form_obj.email.label }}#} {# {{ form_obj.email }}#} forms组件渲染标签的方式3(封装程度较高 扩展性高 编写简单 推荐使用) {# {% for form in form_obj %}#} {# #} {# {{ form.label }}#} {# {{ form }}#} {# #} {# {% endfor %}#} ``` 注意事项:forms组件负责获取用户数据的标签 也就意味着form标签与按钮都需要自己写 前端的校验是弱不禁风的 最终都需要后端来校验 所以我们在使用forms组件的时候可用直接取消前端帮我们的校验 ```python ``` ## forms组件展示信息 ```python 后端不同请求返回的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 %} {{ form.label }} {{ form }} {{ form.errors.0 }} {% endfor %} 针对错误信息的提示可以修改成各国语言 ``` 方式1:自定义错误内容 给字段对象添加errors_messages参数 ```python username = forms.CharField(min_length=3, max_length=8, label='用户名', error_messages={ 'min_length': '用户名最少三个字符', 'max_length': '用户名最多八个字符', 'required': '用户名不能为空' } ) ```  方式2:修改系统语言环境 ```python 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 第三种类型:钩子函数 编写代码自定义校验规则 钩子函数》》》校验的最后一环 是再字段所有的校验参数之后触发 ```python 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 # 使用完毕后返回回去 ```  ## forms组件参数补充 ```python 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组件源码剖析 ```python 切入口: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 ``` ```python 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组件的强化版 更好用更简便更方便 ```python 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()) ```  Last modification:December 27th, 2022 at 09:26 pm © 允许规范转载 Support 如果觉得我的文章对你有用,请随意赞赏 ×Close Appreciate the author Sweeping payments
Comment here is closed