zoukankan      html  css  js  c++  java
  • 使用Django Form表单

    1.Django Form表单的作用

    Django用Form类描述html表单,帮助或简化操作

    1、接收和处理用户提交的数据

    可检查提交的数据

    可将数据转换成Python的数据类型

    2、可自动生成html代码

    上次登录界面是写在了博客页面,这次应该把它提取出来作为一个公共页面,点击登录时进入这个公共页面,那么上次使用的登录后跳转到

    登录前的博客页面得进行修改,因为上次记录的时本页面的链接,此时进入了一个新的登录页面,上次的方法会跳转到登录页面。

    我们要进入登录之前的页面,最好把这个页面传进来,我们就知道该怎么跳转,有2种方式,一种是GET方式,链接打个?写个参数;POST是在登录表单中

    加入一个字段,写刚才的链接。此时采用GET方式。

    对表单验证通过时,获取用户名,密码,再验证用户名,密码的正确性,正确时成功登陆,错误时失败登陆

    登录成功时返回登录前的博客页面:

    <a href="{% url 'login' %}?from={{ request.get_full_path }}">登录</a>

    from等于一个链接
    通过GET方式传了一个参数
    在views的login方法中,获取from参数,如果没传返回首页。
    return redirect(request.GET.get('from'), reverse('home'))

    登录不成功时,返回用户名或密码错误信息,也可以用错误页面的方法,但是跳来跳去不是很好,可以利用djangofrom本身有个错误集合,login_form本身包含一个错误集,
    可以把错误信息加到错误集,第一个是字段,可能是用户名也可能是密码错误,写None,第二个是错误信息。信息有了后返回form,此时form中就有了错误信息,就会自动显示到
    前端模版页面。
    login_form.add_error(None, '用户名或密码不正确')
    context = {}
    context['login_form'] = login_form
    return render(request, 'login.html', context)

    前端出现的错误显示代码
    <ul class="errorlist nonfield"><li>用户名或密码不正确</li></ul>

    验证不通过时,也会携带错误信息,之后返回form
    context = {}
    context['login_form'] = login_form
    return render(request, 'login.html', context)

    最后代码,登陆逻辑
    def login(request):
        '''username = request.POST.get('username','')
        password = request.POST.get('password','')
        user = auth.authenticate(request, username=username, password=password)
        referer = request.META.get('HTTP_REFERER', reverse('home'))
        if user is not None:
            auth.login(request, user)
            return redirect(referer)
        else:
            return render(request,'error.html',{'message':'用户名或密码不正确'})'''
        if request.method == 'POST':
            login_form = LoginForm(request.POST) #提交相关数据进行初始化
            if login_form.is_valid(): #验证数据是否有效
                username = login_form.cleaned_data['username'] #经过验证的数据可以通过clean_data获取
                password = login_form.cleaned_data['password']
                user = auth.authenticate(request, username=username, password=password)
    
                if user is not None:
                    auth.login(request, user)
                    return redirect(request.GET.get('from'), reverse('home'))
                else:
                    login_form.add_error(None, '用户名或密码不正确')
        else:
            login_form = LoginForm()
            
        context = {}
        context['login_form'] = login_form
        return render(request,'login.html',context)

    感觉DjangoForm对比Html就是,把前端页面写的表单移到了forms文件中,通过views实例化后传到前端页面;forms中还可以进行验证,如用户名密码验证,

    字段验证。执行is_valid()的时候就会进入forms中的一些clean方法中。在forms中经过is_valid()验证后的数据可以通过cleaned_data获取。

    我们可以吧验证的代码都放到forms中,这里是验证用户名和密码是否正确,就可以把views中的验证删除。使得views更加简洁。

    from django import forms
    from django.contrib import auth
    
    class LoginForm(forms.Form):
        username = forms.CharField(label='用户名')
        password = forms.CharField(label='密码', widget=forms.PasswordInput)
    
        def clean(self):
            username = self.cleaned_data['username']
            password = self.cleaned_data['password']
    
            user = auth.authenticate(username=username, password=password)
            if user is None:
                raise forms.ValidationError('用户名或密码不正确')
            else:
                self.cleaned_data['user'] = user
            return self.cleaned_data

    优化views

        if request.method == 'POST':
            login_form = LoginForm(request.POST) #提交相关数据进行初始化
            if login_form.is_valid(): #验证数据是否有效
                user = login_form.cleaned_data['user']
                auth.login(request, user)
                return redirect(request.GET.get('from'), reverse('home'))
        else:
            login_form = LoginForm()
    
        context = {}
        context['login_form'] = login_form
        return render(request,'login.html',context)

    前端页面的显示也可以用bootsrap进行优化

    {#先弄个容器,在弄个行,之后4列宽度,偏移4行到中间,之后把form放到一个带标题的面板里#}
    {#为了去掉冒号需要遍历login_form,之后把他的的label也显示出来,再进行错误的显示;若要对输入框进行美化可以在forms中优化#}
    {% block content %}
        <div class="container">
            <div class="row">
                <div class="col-xs-4 col-xs-offset-4">
                    <div class="panel panel-default">
                        <div class="panel-heading">
                            <h3 class="panel-title">登录</h3>
                        </div>
                        <div class="panel-body">
                            <form action="" method="POST">
                                {% csrf_token %}
                                {% for field in login_form %}
                                    <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                                    {{ field }}
                                    <p class="text-danger">{{ field.errors.as_text }}</p>
                                {% endfor %}
                                <span class="pull-left text-danger">{{ login_form.non_field_errors }}</span>
                                <input type="submit" value="登录" class="btn btn-primary pull-right">
                            </form>
                        </div>
                    </div>
    
                </div>
            </div>
        </div>
    #优化输入框
    class
    LoginForm(forms.Form): username = forms.CharField(label='用户名', widget=forms.TextInput(attrs={'class':'form-control', 'placeholder':'请输入用户名'})) password = forms.CharField(label='密码', widget=forms.PasswordInput(attrs={'class':'form-control', 'placeholder':'请输入密码'}))

    登录写完了,再写注册

    依次写forms,urls,前端,views。

    forms

    class RegForm(forms.Form):
        username = forms.CharField(label='用户名',
                                   max_length=30,
                                   min_length=3,
                                   widget=forms.TextInput(attrs={'class':'form-control', 'placeholder':'请输入3-30位用户名'}))
        email = forms.EmailField(label='邮箱',
                                 widget=forms.EmailInput(attrs={'class':'form-control', 'placeholder':'请输入邮箱'}))
        password = forms.CharField(label='密码',
                                   min_length=6,
                                   widget=forms.PasswordInput(attrs={'class':'form-control', 'placeholder':'请输入密码'}))
        password_again = forms.CharField(label='密码',
                                         min_length=6,
                                         widget=forms.PasswordInput(attrs={'class':'form-control', 'placeholder':'再输入一次密码'}))
    
        def clean_username(self):
            username = self.cleaned_data['username']
            if User.objects.filter(username=username).exists():
                raise forms.ValidationError('用户名已存在')
            return username
    
        def clean_email(self):
            email = self.cleaned_data['email']
            if User.objects.filter(email=email).exists():
                raise forms.ValidationError('邮箱已存在')
            return email
    
        def clean_password_again(self):
            password = self.cleaned_data['password']
            password_again = self.cleaned_data['password_again']
            if password != password_again:
                raise forms.ValidationError('两次输入的密码不一致')
            return password_again

    urls

        path('register/', views.register,name='register'),

    前端

    {% extends 'base.html' %}
    {% load staticfiles %}
    
    {% block title %}
        我的网站|注册
    {% endblock %}
    
    {% block nav_home_active %}active{% endblock %}
    
    {#先弄个容器,在弄个行,之后4列宽度,偏移4行到中间,之后把form放到一个带标题的面板里#}
    {#为了去掉冒号需要遍历reg_form,之后把他的的label也显示出来,再进行错误的显示;若要对输入框进行美化可以在forms中优化#}
    {% block content %}
        <div class="container">
            <div class="row">
                <div class="col-xs-4 col-xs-offset-4">
                    <div class="panel panel-default">
                        <div class="panel-heading">
                            <h3 class="panel-title">注册</h3>
                        </div>
                        <div class="panel-body">
                            <form action="" method="POST">
                                {% csrf_token %}
                                {% for field in reg_form %}
                                    <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                                    {{ field }}
                                    <p class="text-danger">{{ field.errors.as_text }}</p>
                                {% endfor %}
                                <span class="pull-left text-danger">{{ reg_form.non_field_errors }}</span>
                                <input type="submit" value="登录" class="btn btn-primary pull-right">
                            </form>
                        </div>
                    </div>
    
                </div>
            </div>
        </div>
    
    {% endblock %}

    views

    def register(request):
        if request.method == 'POST':
            reg_form = RegForm(request.POST) #提交相关数据进行初始化
            if reg_form.is_valid(): #验证数据是否有效,之后获取数据
                username = reg_form.cleaned_data['username']
                email = reg_form.cleaned_data['email']
                password = reg_form.cleaned_data['password']
                #创建用户
                user = User.objects.create_user(username,email,password)
                user.save()
                #登录用户
                user = auth.authenticate(username=username,password=password)
                auth.login(request,user)
                #跳转到进入注册页面之前的路径
                return redirect(request.GET.get('from'), reverse('home'))
        else:
            reg_form = RegForm()
    
        context = {}
        context['reg_form'] = reg_form
        return render(request,'register.html',context)




  • 相关阅读:
    Android开发使用Glide获取图片背景色淡绿色解决办法
    Android 获取 View 宽高的常用正确方式,避免为零
    Android之自定义View来接收输入法输入的内容
    FileProvider使用详解(拍照、安装APP、共享文件)
    简明 homebrew
    更优雅地使用命令行
    一篇长文说 git 基础
    chrome 浏览器的使用技巧
    前端学命令行
    cocos 碰撞系统
  • 原文地址:https://www.cnblogs.com/lag1/p/13866910.html
Copyright © 2011-2022 走看看