form与modelform

form组件

1 生成html标签
2 保留原来的数据
3 校验用户提交的数据
如何给生成的标签加样式

利用Form自动生成HTML标签

第1步 在views.py文件中 导入from django import forms模块 定义一个类 继承与forms.Form  名字随意  继承forms.Form
第2步 修改forms.后面的  变更不同属性
第3步 修改forms.widgets.后面的 变更不同标签
第4步 实列化这个类 传给后端
第5步 写后端代码
    {{对象.字段.label }}就是自定义名字
    {{ 对象.字段 }} 就会生成标签
    {{ 对象.字段.errors.0 }}就会生成错误信息 第1个

from django import forms
#生成用户名输入框 name对应username vluse对应用户输入的值
class UserInfo(forms.Form):
     username=forms.CharField(
        label='用户名:',
        initial="张三",#默认值
        widget=forms.widgets.TextInput,
)
#生成密码输入框 name对应password vluse对应用户输入的值
    password=forms.CharField(
        label='密码:',
        widget=forms.widgets.PasswordInput(attrs={'class':'c1'}),---attrs里面可以添加属性
    )
#生成单选框 默认下拉框 name对应 sex vluse对应用户选择的值
    sex = forms.ChoiceField(
        choices=((1,'女'),(2,'男'),),#元祖套列表或元祖套元祖
        # widget=forms.RadioSelect,----修改成这样变成小圆点选择框
        # widget=forms.widgets.Select,---这是下拉框 默认就是
    )
#生成多选框 默认下拉框 name对应 hobby vluse对应用户选择的值
    hobby = forms.MultipleChoiceField(
        choices= ((1,'喝酒'),(2,'抽烟'),(3,'烫头')),
        # widget=forms.SelectMultiple,---这是下拉框 默认就是
        widget=forms.CheckboxSelectMultiple,---修改成小方块选择框
    )
#生成 选中框 name对应 remember_me
    remember_me = forms.ChoiceField(
        label='记住我',

        widget=forms.CheckboxInput,
    )
#生成 日期选择框 name对应 bday
    bday = forms.DateField(
        label='出生日期',
        # 日期类型必须加上日期属性
        widget=forms.DateInput(attrs={'type':'date'}),  

    )

def index(request):

    if request.method == 'GET':
        u_obj = UserInfo()#实列化对象
        return render(request,'index.html',{'u_obj':u_obj})

    else:

        u_obj = UserInfo(request.POST)  #用户提交的数据给类 进行实例化
        if u_obj.is_valid():#效验用户数据
            # {'username': 'a范德萨水电费', 'password': '1111'}
            print('正确数据',u_obj.cleaned_data)  #校验成功之后的数据cleaned_data

            return HttpResponse('ok')
        else:
            # print('错误信息',u_obj.errors)

            return render(request,'index.html',{'u_obj':u_obj})

前端模板写法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .c1{
            background-color: red;
        }
    </style>
</head>
<body>

<h1>某某登录页面</h1>
{#{{ u_obj.errors }}#}全部报错信息

<form action="" method="post" novalidate>
    {% csrf_token %} 安全验证
{#    用户名: <input type="text" name="username">#}
{#    密码: <input type="password" name="password">#}

        {{ u_obj.username.label }} {{ u_obj.username }} {{ u_obj.username.errors.0 }}
    </div>
   <div>
        {{ u_obj.password.label }} {{ u_obj.password }} {{ u_obj.password.errors.0 }}
   </div>
    <div>
        {{ u_obj.r_password.label }} {{ u_obj.r_password }} {{ u_obj.r_password.errors.0 }}
   </div>

    <input type="submit">

</form>

利用form保留原来的数据

默认自动保留
password不会自动保留数据在widget里面添加render_value=True就可以强制留下
    r_password = forms.CharField(
        label='确认密码:',
        widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True),

    )
render_value=True强制留

利用form校验用户提交的数据

简单效验用户数据

u_obj.password.errors.0 获得第一个错误数据

常见属性
    min_length设置用户输入长度最小值
    max_length设置用户输入长度最大值
    required=True,  #不允许输入为空,值为False就可以为空

自定义错误信息后就不会显示英文的了
error_messages={
            'required':'不能为空',
            'min_length':'太短了!',
            'max_length':'太长了!',
        },

注意浏览器会自动帮你效验 要想浏览器不效验 在前端代码设置(novalidate)提示浏览器不要多管闲事
 <form action="" method="post" novalidate>

下面的代码实列

    username=forms.CharField(
        label='用户名:',
        # initial='张三'  #默认值
        # min_length=6, #最小值为6位
        # required=True,  #不允许为空,值为False就可以为空
        # widget=forms.widgets.TextInput,
        # max_length=8,

        error_messages={
            'required':'不能为空',
            'min_length':'太短了!',
            'max_length':'太长了!',
        },
        validators=[RegexValidator(r'^a','必须以a开头!'),RegexValidator(r'b$','必须以b结尾!')]
        # validators=[mobile_validate,]  #a范德萨水电费

    )
    

正则校验器RegexValidator验证器

第一步引入模块from django.core.validators import RegexValidator
第2步定义规则  可以定义多个规则
validators=[RegexValidator(r'^a','必须以a开头!'),RegexValidator(r'b$','必须以b结尾!')] 第一个参数是正则 第2个参数是错误信息

下面是代码实列

    username=forms.CharField(
        label='用户名:',
        initial='张三'  #默认值
        min_length=6, #最小值为6位
        required=True,  #不允许为空,值为False就可以为空
        widget=forms.widgets.TextInput,
        max_length=8,

        error_messages={
            'required':'不能为空',
            'min_length':'太短了!',
            'max_length':'太长了!',
        },
        validators=[RegexValidator(r'^a','必须以a开头!'),RegexValidator(r'b$','必须以b结尾!')]

自定义验证规则

当正则效验 与基础效验 满足不了 我们就需要  自定义验证规则了( )
第1步引入模块
    from django.core.exceptions import ValidationError
    import re
第2步定义一个函数
    函数里面value是形参 传要验证的字符串
    mobile_re是利用re模块编译出来的正则规则
    利用ValidationError抛出错误

 def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手机号码格式错误')
第3步 在类里面 验证类里面加入·
    validators=[定义的函数名,]

代码实列

from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError

import re
def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手机号码格式错误') 

class UserInfo(forms.Form):

    username=forms.CharField(
        label='用户名:',
        # initial='张三'  #默认值
        # min_length=6, #最小值为6位
        # required=True,  #不允许为空,值为False就可以为空
        # widget=forms.widgets.TextInput,
        # max_length=8,

        error_messages={
            'required':'不能为空',
            'min_length':'太短了!',
            'max_length':'太长了!',
        },
        validators=[RegexValidator(r'^a','必须以a开头!'),RegexValidator(r'b$','必须以b结尾!')]
        validators=[mobile_validate,]  #a范德萨水电费

    )

    password=forms.CharField(
        label='密码:',
        widget=forms.widgets.PasswordInput(attrs={'class':'c1'},render_value=True),

    )

    r_password = forms.CharField(
        label='确认密码:',
        widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True),

    )

    # 局部钩子
    def clean_username(self):
        value = self.cleaned_data.get('username')
        if '666' in value:
            raise ValidationError('光喊666是不行的!')
        else:
            return value

    # 全局钩子
    def clean(self):
        password = self.cleaned_data.get('password')
        r_password = self.cleaned_data.get('r_password')

        if password == r_password:
            return self.cleaned_data
        else:
            # raise ValidationError('两次密码不一致!!!!')
            self.add_error('r_password','两次密码不一致~~~~') # 给单独的某个字段加错误信息

def index(request):
    if request.method == 'GET':
        u_obj = UserInfo()
        return render(request,'index.html',{'u_obj':u_obj})
    else:
效验
        u_obj = UserInfo(request.POST)  #{'username':'','password':'123'}
        print(u_obj.fields)
        # u_obj.is_valid()  #校验用户提交的数据,全部校验成功返回True,任意一个失败都返回False
        if u_obj.is_valid():
            # {'username': 'a范德萨水电费', 'password': '1111'}
            print('正确数据',u_obj.cleaned_data)  #校验成功之后的数据cleaned_data

            return HttpResponse('ok')
        else:
            # print('错误信息',u_obj.errors)

            return render(request,'index.html',{'u_obj':u_obj})

Hook钩子方法

局部钩子

第1步 我们在Fom类中定义 clean_字段() 方法,就能够实现对特定字段进行校验。
注意事项
    效验顺序是先效验字段里面的效验规则 然后在效验局部钩子 最后下一字段

实列写法(cleaned_data是效验以后得到的数据)
def clean_username(self):
        value = self.cleaned_data.get('username')
        if '666' in value:
            raise ValidationError('光喊666是不行的!')--错误信息
        else:
            return value--一定要返回不然会吧username对应的value剔除
钩子是写在类里面

代码实列

from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError

import re
def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手机号码格式错误') 

class UserInfo(forms.Form):

    username=forms.CharField(
        label='用户名:',
        # initial='张三'  #默认值
        # min_length=6, #最小值为6位
        # required=True,  #不允许为空,值为False就可以为空
        # widget=forms.widgets.TextInput,
        # max_length=8,

        error_messages={
            'required':'不能为空',
            'min_length':'太短了!',
            'max_length':'太长了!',
        },
        validators=[RegexValidator(r'^a','必须以a开头!'),RegexValidator(r'b$','必须以b结尾!')]
        validators=[mobile_validate,]  #a范德萨水电费

    )

    password=forms.CharField(
        label='密码:',
        widget=forms.widgets.PasswordInput(attrs={'class':'c1'},render_value=True),

    )

    r_password = forms.CharField(
        label='确认密码:',
        widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True),

    )

    # 局部钩子
    def clean_username(self):
        value = self.cleaned_data.get('username')
        if '666' in value:
            raise ValidationError('光喊666是不行的!')
        else:
            return value

    # 全局钩子
    def clean(self):
        password = self.cleaned_data.get('password')
        r_password = self.cleaned_data.get('r_password')

        if password == r_password:
            return self.cleaned_data
        else:
            # raise ValidationError('两次密码不一致!!!!')
            self.add_error('r_password','两次密码不一致~~~~') # 给单独的某个字段加错误信息

def index(request):
    if request.method == 'GET':
        u_obj = UserInfo()
        return render(request,'index.html',{'u_obj':u_obj})
    else:
效验
        u_obj = UserInfo(request.POST)  #{'username':'','password':'123'}
        print(u_obj.fields)
        # u_obj.is_valid()  #校验用户提交的数据,全部校验成功返回True,任意一个失败都返回False
        if u_obj.is_valid():
            # {'username': 'a范德萨水电费', 'password': '1111'}
            print('正确数据',u_obj.cleaned_data)  #校验成功之后的数据cleaned_data

            return HttpResponse('ok')
        else:
            # print('错误信息',u_obj.errors)

            return render(request,'index.html',{'u_obj':u_obj})

全局钩子

句部钩子全部指行完 在执行全局  比如多个字段对比效验, 比如确认密码
函数名固定写法
def clean(self):
    password = self.cleaned_data.get('password')
    r_password = self.cleaned_data.get('r_password')

    if password == r_password:#效验成功了L
        return self.cleaned_data---固定写法 cleaned_data源码里有
    else:
        # raise ValidationError('两次密码不一致!!!!')不用因为给全局了
        self.add_error('r_password','两次密码不一致~~~~') # 给单独的某个字段加错误信息

代码实列

from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError

import re
def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手机号码格式错误') 

class UserInfo(forms.Form):

    username=forms.CharField(
        label='用户名:',
        # initial='张三'  #默认值
        # min_length=6, #最小值为6位
        # required=True,  #不允许为空,值为False就可以为空
        # widget=forms.widgets.TextInput,
        # max_length=8,

        error_messages={
            'required':'不能为空',
            'min_length':'太短了!',
            'max_length':'太长了!',
        },
        validators=[RegexValidator(r'^a','必须以a开头!'),RegexValidator(r'b$','必须以b结尾!')]
        validators=[mobile_validate,]  #a范德萨水电费

    )

    password=forms.CharField(
        label='密码:',
        widget=forms.widgets.PasswordInput(attrs={'class':'c1'},render_value=True),

    )

    r_password = forms.CharField(
        label='确认密码:',
        widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True),

    )

    # 局部钩子
    def clean_username(self):
        value = self.cleaned_data.get('username')
        if '666' in value:
            raise ValidationError('光喊666是不行的!')
        else:
            return value

    # 全局钩子
    def clean(self):
        password = self.cleaned_data.get('password')
        r_password = self.cleaned_data.get('r_password')

        if password == r_password:
            return self.cleaned_data
        else:
            # raise ValidationError('两次密码不一致!!!!')
            self.add_error('r_password','两次密码不一致~~~~') # 给单独的某个字段加错误信息

def index(request):
    if request.method == 'GET':
        u_obj = UserInfo()
        return render(request,'index.html',{'u_obj':u_obj})
    else:
效验
        u_obj = UserInfo(request.POST)  #{'username':'','password':'123'}
        print(u_obj.fields)
        # u_obj.is_valid()  #校验用户提交的数据,全部校验成功返回True,任意一个失败都返回False
        if u_obj.is_valid():
            # {'username': 'a范德萨水电费', 'password': '1111'}
            print('正确数据',u_obj.cleaned_data)  #校验成功之后的数据cleaned_data

            return HttpResponse('ok')
        else:
            # print('错误信息',u_obj.errors)

            return render(request,'index.html',{'u_obj':u_obj})

利用from实现页面

   # 批量添加属性样式
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        for field_name,field in self.fields.items(): #orderdict(('username',charfield对象))

            field.widget.attrs.update({'class':'form-control'})

modelform组件

class BookModelForm(forms.ModelForm):
    # 优先级高
    # title = forms.CharField(
    #     label='书名2',
    # )

    class Meta:
        model = models.Book
        #fields='__all__'
        fields=['title','publishs']
        labels={
            'title':'书名',
            'price':'价格',
            'publishDate':'出版日期',
            'publishs':'出版社',
            'authors':'作者',
        }

        widgets={
            'publishDate':forms.TextInput(attrs={'type':'date'}),
            # 'publishDate2':forms.TextInput(attrs={'type':'date'}),
        }

        error_messages={
            'title':{'required':'书名不能为空!',},
            'price':{'required':'不能为空!',},
            'publishDate':{'required':'不能为空!',},
            'publishs':{'required':'不能为空!',},
            'authors':{'required':'不能为空!',},
        }

    #
    # def clean_title(self):
    #     pass
    # def clean(self):
    #     pass

    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        for field_name,field in self.fields.items():
            field.widget.attrs.update({'class':'form-control'})

为什么要有modelform组件

 举个例子,你也许会有个Book 模型,并且你还想创建一个form表单用来添加和编辑书籍信息到这个模型中。 在这种情况下,在form表单中定义字段将是冗余的,因为我们已经在模型中定义了那些字段。
  基于这个原因,Django 提供一个辅助类来让我们可以从Django 的模型创建Form,这就是ModelForm。
form与model的终极结合,会根据你model中的字段转换成对应的form字段,并且并你生成标签等操作。

modelform组件怎么用

第一步定义一个类 名字随便取 最好有含义 列入BookModelForm
类里面定义
    class Meta:
            model = models.Book
            #fields='__all__' 拿到所有字段 生成from字段

class BookModelForm(forms.ModelForm):#类目随便取
    # 优先级高
    # title = forms.CharField(
    #     label='书名2',
    # )

    class Meta:
        model = models.Book#找到book表
        fields='__all__' #拿到所有字段 生成from字段
        #fields=['title','publishs']
        labels={
            'title':'书名',
            'price':'价格',
            'publishDate':'出版日期',
            'publishs':'出版社',
            'authors':'作者',
        }

        widgets={
            'publishDate':forms.TextInput(attrs={'type':'date'}),
            # 'publishDate2':forms.TextInput(attrs={'type':'date'}),
        }

        error_messages={
            'title':{'required':'书名不能为空!',},
            'price':{'required':'不能为空!',},
            'publishDate':{'required':'不能为空!',},
            'publishs':{'required':'不能为空!',},
            'authors':{'required':'不能为空!',},
        }

    #
    # def clean_title(self): 钩子
    #     pass
    # def clean(self):
    #     pass

    def __init__(self,*args,**kwargs):#还是和from一样给所有字段添加样式
        super().__init__(*args,**kwargs)
        for field_name,field in self.fields.items():
            field.widget.attrs.update({'class':'form-control'})

同源和跨域

同源机制:域名、协议、端口号相同的同源

简单请求
(1) 请求方法是以下三种方法之一:(也就是说如果你的请求方法是什么put、delete等肯定是非简单请求)
    HEAD
    GET
    POST
(2)HTTP的头信息不超出以下几种字段:(如果比这些请求头多,那么一定是非简单请求)
    Accept
    Accept-Language
    Content-Language
    Last-Event-ID
    Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain,也就是说,如果你发送的application/json格式的数据,那么肯定是非简单请求,vue的axios默认的请求体信息格式是json的,ajax默认是urlencoded的。

    #vue.js axios -- $.ajax
支持跨域,简单请求

    服务器设置响应头:Access-Control-Allow-Origin = '域名' 或 '*'

  支持跨域,复杂请求

    由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据。

      “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method

      “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers
    res['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8001'
    res['Access-Control-Allow-Headers'] = 'content-type' 所有的content-type
    # res['Access-Control-Allow-Methods'] = 'PUT'
    # res['Access-Control-Allow-Origin'] = '*'

原文地址:https://www.cnblogs.com/saoqiang/p/12397718.html

时间: 2024-11-09 06:19:34

form与modelform的相关文章

Model、Form、ModelForm

本节内容: 1:Model 2:Form 3:Model 1 2 3 http://www.cnblogs.com/wupeiqi/articles/6144178.html  武sir:Form组件 http://www.cnblogs.com/wupeiqi/articles/6216618.html  武sir:Model http://www.cnblogs.com/wupeiqi/articles/6229414.html  武sir:ModelForm Model ==> 强大的数据

Django 中的Form、ModelForm

一.ModelForm 源码 class ModelForm(BaseModelForm, metaclass=ModelFormMetaclass): pass def modelform_factory(model, form=ModelForm, fields=None, exclude=None, formfield_callback=None, widgets=None, localized_fields=None, labels=None, help_texts=None, erro

Django Form和ModelForm组件

Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确.如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.. Django form组件就实现了上面所述的功能. 总结一下,其实form组件的主要功能如下: 生成页面可用的HTML标签 对用户提交的数据进行校验 保留上次输入内容 普通方式手写注册功能 vi

Form和ModelForm组件

Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确.如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.. Django form组件就实现了上面所述的功能. 总结一下,其实form组件的主要功能如下: 生成页面可用的HTML标签 对用户提交的数据进行校验 保留上次输入内容 普通方式手写注册功能 vi

12.Django基础十之Form和ModelForm组件

一 Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确.如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.. Django form组件就实现了上面所述的功能. 总结一下,其实form组件的主要功能如下: 生成页面可用的HTML标签 对用户提交的数据进行校验 保留上次输入内容 普通方式手写注册功能

Django基础十之Form和ModelForm组件

一 Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确.如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.. Django form组件就实现了上面所述的功能. 总结一下,其实form组件的主要功能如下: 生成页面可用的HTML标签 对用户提交的数据进行校验 保留上次输入内容 普通方式手写注册功能

Form和ModelForm组件1

Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确.如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.. Django form组件就实现了上面所述的功能. 总结一下,其实form组件的主要功能如下: 生成页面可用的HTML标签 对用户提交的数据进行校验 保留上次输入内容 普通方式手写注册功能 vi

原生Form 和 Form组件 Modelform

主要的文件:manage.py,url.py,views.py,settings.py,models.py manage.py:项目管理文件,一般不做修改. url.py:路由系统,配置views.py中函数和对应路径的关系. views.py:添加视图函数,常见的增删查改函数. settings.py:模板配置文件,对TEMPLATES .DATABASES.STATIC_URL 等进行配置. models.py:数据库相关表的类描述. Django基础必备三件套:HttpResponse,

Django Form and ModelForm

Form介绍 在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确.如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.. Django form组件就实现了上面所述的功能. 总结一下,其实form组件的主要功能如下: 生成页面可用的HTML标签 对用户提交的数据进行校验 保留上次输入内容 普通方式手写注册功能 views.