Django之form组件!

Posted sima-3

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django之form组件!相关的知识,希望对你有一定的参考价值。

 一.手动实现注册功能

        注册功能
            1.渲染前端标签获取用户输入      >>>       渲染标签
            2.获取用户输入传递到后端校验    >>>       校验数据
            3.校验未通过展示错误信息        >>>       展示信息
    
        
        校验数据(前后端都可以校验)
            校验前端后端都可以做,但是前端可以不做,后端必须得做!!!

 

     后端:

 

def reg(request):
    errors=username:‘‘,password:‘‘
    if request.method == POST:
        username=request.POST.get(username)
        password=request.POST.get(password)
        if sb in username:
            errors[username]=user is not valid
        if password == 123:
            errors[password]=too easy

    return render(request,reg.html,locals())

 

     前端:

<body>
<h1>注册页面</h1>
<form action="" method="post">
    <p>username:
        <input type="text" name="username">
        <span> errors.username </span>
    </p>
    <p>password:
        <input type="password" name="password">
        <span> errors.password </span>
    </p>
    <input type="submit">

</form>
</body>

效果:

       技术图片

 

二. django form组件

        1.渲染标签
        2.校验数据
        3.展示信息

    1.校验数据:

         测试小技巧:      

           技术图片

 

 

  

            第一步需要一个form类
                from django import forms

                class MyForm(forms.Form):
                    name = forms.CharField(max_length=6)
                    password = forms.CharField(max_length=8,min_length=3)
                    email = forms.EmailField(required=True)
            第二步实例化form对象
                from app01 import views
                                form_obj=views.MyForm(name:jasonhaha,password:12,email:123)
            
            第三步查看数据校验是否合法
                form_obj.is_valid()  # 只有当所有的字段都校验通过才会返回True
            
            第四步查看校验错误的信息
                form_obj.errors  # 这个里面放的是所有校验未通过的字段及错误提示
                """
                
                ‘name‘: [‘Ensure this value has at most 6 characters (it has 7).‘], 
                ‘password‘: [‘Ensure this value has at least 3 characters (it has 2).‘], 
                ‘email‘: [‘Enter a valid email address.‘]
                

                """
            第五步查看校验通过的数据
                form_obj.cleaned_data  # 符合校验规则数据都会被放到该对象中
            ps:form组件校验数据的规则从上往下依次取值校验
                校验通过的放到cleaned_data
                校验失败的放到errors

              注意:
                   form中所有的字段默认都是必须传值的(required=True),不想传可以改成False
                   校验数据的时候可以都传(多传的数据不会做任何的校验>>>不会影响form校验规则)


      2.渲染标签:

            后端:

from django import forms

class MyForm(forms.Form):
    name = forms.CharField(max_length=6,label=‘用户名‘)
#不写label,则在前端显示的是Name password
= forms.CharField(max_length=8,min_length=3) email=forms.EmailField(required=False) def reg(request): form_obj = MyForm() render(request,reg.html,locals())

         前端:

            form组件只帮你渲染获取用户输入的标签,不会帮你渲染提交按钮,需要手动添加
            <h1>第一种渲染方式(可扩展性较差)</h1>
             form_obj.as_p 
             form_obj.as_ul 
            <input type="submit">

<h1>第二种渲染方式</h1> <form action=""> <p> form_obj.name.label form_obj.name </p>
#label可标识前面的注释 <p> form_obj.password.label form_obj.password </p> <p> form_obj.email.label form_obj.email </p> <input type="submit"> </form>
<h1>第三种渲染标签的方式</h1> <form action=""> % for foo in form_obj % <p> foo.label foo </p> % endfor %
              <input type="submit">
            </form>

    

     前端取消校验:

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

    3.form组件前后端综合使用

         后端:

 

from django import forms

class MyForm(forms.Form):
    name = forms.CharField(max_length=6)
    password = forms.CharField(max_length=8,min_length=3)
    email=forms.EmailField(required=True)

def reg(request):
    form_obj = MyForm()
    if request.method == POST:
        print(request.POST)
        form_obj = MyForm(request.POST)
        if form_obj.is_valid():
            return HttpResponse(ok)
    return render(request,reg.html,locals())

 

     前端:

<h1>第三种渲染标签的方式</h1>
<form action="" method="post" novalidate>
    % for foo in form_obj %   #foo是每一个输入框对象
        <p>
             foo.label  foo 
            <span> foo.errors.0 </span>
        </p>
    % endfor %
<input type="submit">

   

          form组件提交数据如果数据不合法,页面上会保留之前用户输入的信息
 

效果:

  技术图片

 

 错误提示可以自定义成中文:

class MyForm(forms.Form):
    name = forms.CharField(max_length=6,label=用户名,error_messages=
        max_length:用户名最长6位,
        required:用户名不能为空
    )
    password = forms.CharField(max_length=8,min_length=3,error_messages=
        max_length: 密码最长8位,
        required: 密码不能为空,
        min_length:密码最少3位
    

    email = forms.EmailField(error_messages=
        invalid:邮箱格式不正确,
        required:邮箱不能为空
    )

效果:

  技术图片

  4.把注册信息写入数据库:

    models.py:

from django.db import models

# Create your models here.
class User(models.Model):
    name = models.CharField(max_length=32)
    password = models.CharField(max_length=32)
    email = models.EmailField()

  后端:

def reg(request):
    form_obj = MyForm()
    if request.method == POST:
        print(request.POST)
        form_obj = MyForm(request.POST)
        if form_obj.is_valid():
            data=form_obj.cleaned_data
            models.User.objects.create(**data)
    return render(request,reg.html,locals())

ps:

在使用form组件对模型表进行数据校验的时候,只需要保证字段一致
那么在创建的对象的时候,把校验通过后的字典键值对拿过来,就直接**form_obj.cleaned_data

效果:

  技术图片

三. form 钩子函数

            # 局部钩子函数  (单个字段的校验利用局部钩子函数)
            def clean_name(self):
                name = self.cleaned_data.get(name)
                if 666 in name:
                    self.add_error(name,光喊666是不行的,要有真实力!)
                return name  # return还是要加上的,兼容性考虑

            # 全局钩子函数  (多个字段的校验利用全局钩子函数)
            def clean(self):
                password = self.cleaned_data.get(password)
                confirm_password = self.cleaned_data.get(confirm_password)
                if not password == confirm_password:
                    self.add_error(confirm_password,"两次密码不一致,你这个dsb!")
                return self.cleaned_data

四. forms.widgets的相关用法(可设置标签样式)

class MyForm(forms.Form):
    name = forms.CharField(max_length=6,label=用户名,error_messages=
        max_length:用户名最长6位,
        required:用户名不能为空
    )
    password = forms.CharField(max_length=8,min_length=3,error_messages=
        max_length: 密码最长8位,
        required: 密码不能为空,
        min_length:密码最少3位
    ,widget=widgets.PasswordInput(attrs=class:c1 form-control))
    confirm_password = forms.CharField(max_length=8, min_length=3, error_messages=
        max_length: 确认密码最长8位,
        required: 确认密码不能为空,
        min_length: 确认密码最少3位
    ,widget=widgets.PasswordInput())
    email = forms.EmailField(error_messages=
        invalid:邮箱格式不正确,
        required:邮箱不能为空
    )

    gender = forms.ChoiceField(
        choices=((1, ""), (2, ""), (3, "保密")),
        label="性别",
        initial=3,  # 默认值
        widget=forms.widgets.Radioselect()
    )

    hobby = forms.ChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=3,
        widget=forms.widgets.Select()
    )
    hobby1 = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.SelectMultiple()
    )

    keep = forms.ChoiceField(
        label="是否记住密码",
        initial="checked",
        widget=forms.widgets.CheckboxInput()
    )

效果:

      技术图片

五.django操作cookie,session

 

        http协议四大特性
            1.基于TCP/IP作用于应用层的协议
            2.基于请求响应
            3.无状态
            4.无连接
            
        cookie
            保存在客户端浏览器上的键值对
        
        
        session
            保存在服务端上的键值对
            服务端产生随机的串儿返回给客户端,服务端找一个地方将串儿与对应的信息存起来随机字符串:敏感信息

 

  1.cookie:

        django
            return HttpResponse()
            return render()
            return redirect()
        
        
            obj = HttpResponse()
            return obj
            obj = render()
            return obj
            obj = redirect()
            return obj
        
            
            设置cookie
                obj.set_cookie()  # 给浏览器设置cookie
            
            获取cookie
                request.COOKIE.get(name)
                request.COOKIE[name]

cookie版登录认证:

def login(request):
    if request.method == POST:
        username = request.POST.get(username)
        password = request.POST.get(password)
        if username == jason and password == 123:
#判断是否有想要跳转的页面,如果没有则跳到主页 old_path
= request.GET.get(next) if old_path: obj = redirect(old_path) else: obj = redirect(/home/) # 用户登录成功 朝浏览器设置一个cookie # obj.set_cookie(‘name‘,‘jason‘,expires=7*24*3600) # obj.set_cookie(‘name‘,‘jason‘,max_age=5)
注释:cookie生命周期为5s
obj.set_cookie(name,jason) return obj return render(request,login.html) from functools import wraps def login_auth(func): @wraps(func) def inner(request,*args,**kwargs): # 校验cookie # print(request.get_full_path()) old_path = request.get_full_path() if request.COOKIES.get(name): return func(request,*args,**kwargs) return redirect(/login/?next=%s%old_path) return inner @login_auth def index(request): print(request.COOKIES.get(name)) # if request.COOKIES.get(‘name‘): return HttpResponse(我是index页面,只有登录了才能看) @login_auth def home(request): return HttpResponse(我是home页面,只有登录了才能看) @login_auth def xxx(request): return HttpResponse(我是xxx页面,只有登录了才能看) def logout(request): rep = redirect("/login/") rep.delete_cookie("user") # 删除用户浏览器上之前设置的usercookie值 return rep

 

2.session:

            设置session
                request.session[name] = jason
                # 1.先生成一个随机的字符串
                # 2.在django session表中存储该随机字符串与数据的记录
                # 3.将随机的字符串发送给客户端浏览器
                
            获取session
                request.session.get(name)
                # 1.django自动获取浏览器随机字符串取django session表里面比对
                # 2.如果比对成功 会将当前随机字符串对应的数据赋值给request.session
                # 3.通过request.session操作该数据(数据不存在也不会影响我们的业务逻辑)

django默认的session存活时间是两周(14天),每个浏览器只有一条数据:

技术图片

def set_session(request):
    request.session[name] = jason
    request.session[name1] = egon
    request.session[name2] = tank
    request.session[name3] = nick
    request.session[name4] = sean
    return HttpResponse(ok)

def get_session(request):
    print(request.session.get(name))
    print(request.session.get(name1))
    print(request.session.get(name2))
    print(request.session.get(name3))
    print(request.session.get(name4))
    return HttpResponse(ok)


def delete_session(request):
    request.session.delete()
    return HttpResponse(ok)


def flush_session(request):
    request.session.flush()
    return HttpResponse(ok)
        浏览器会设置一个键为sessionid来存放session值
                
        
        # 删除当前会话的所有Session数据
        request.session.delete()
          
        # 删除当前的会话数据并删除会话的Cookie。
        request.session.flush() 
        这用于确保前面的会话数据不可以再次被用户的浏览器访问
        例如,django.contrib.auth.logout() 函数中就会调用它。
        浏览器会设置一个键为sessionid来存放session值
                
        
        # 删除当前会话的所有Session数据
        request.session.delete()
          
        # 删除当前的会话数据并删除会话的Cookie。
        request.session.flush() 
        这用于确保前面的会话数据不可以再次被用户的浏览器访问
        例如,django.contrib.auth.logout() 函数中就会调用它。

session版登录认证:

from functools import wraps


def check_login(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        next_url = request.get_full_path()
        if request.session.get("user"):
            return func(request, *args, **kwargs)
        else:
            return redirect("/login/?next=".format(next_url))
    return inner


def login(request):
    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")

        if user == "alex" and pwd == "alex1234":
            # 设置session
            request.session["user"] = user
            # 获取跳到登陆页面之前的URL
            next_url = request.GET.get("next")
            # 如果有,就跳转回登陆之前的URL
            if next_url:
                return redirect(next_url)
            # 否则默认跳转到index页面
            else:
                return redirect("/index/")
    return render(request, "login.html")


@check_login
def logout(request):
    # 删除所有当前请求相关的session
    request.session.delete()
    return redirect("/login/")


@check_login
def index(request):
    current_user = request.session.get("user", None)
    return render(request, "index.html", "user": current_user)

 

以上是关于Django之form组件!的主要内容,如果未能解决你的问题,请参考以下文章

django之Form组件

django之forms组件

Django之Form组件

69django之Form组件

django之form组件cookiesession

Django之Form组件