使用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)

 

 

 





posted @ 2020-10-26 20:05  十方劫  阅读(300)  评论(0)    收藏  举报