• 【15】网站搭建:用户注册登录


    一、前言

      这几天正好学了Flask的用户注册登录功能设计,发现与Django的使用特别类似,所以学习Flask的同时也加强了我对Django表单的印象。正好网站搭建也差不多更新到用户操作部分了,就索性把Django表单相关知识再推进一下。其实要加入用户操作功能,也可以直接在模板页面中加上form标签,然后在视图中利用requets.POST.get来接收键值,最后保存在数据库中,所以不是非要使用Django的表单功能才能设计。使用表单是因为表单的确能简化用户在提交用户信息的相关处理,如输入内容不能为空,邮箱必须带有@字符等,这些验证表单的合法性最后都可以交给Django的表单来执行。

      因为在Django中,有比较全的用户模块,所以我没有另外去创建models.py来定义用户的模型,这已经在Django中实现了。我只创建了forms.py用来加入表单字段,另外引用了Django自带的User类。用户的注册登录功能可以比较好的涵盖form表单的相关知识点,常用的form字段定义在官方文档都有说明:表格字段

    二、用户注册

      我在注册表单中,需要用户名,邮箱,密码等输入。

    from django import forms  # django表单功能
    from django.contrib.auth.models import User
    
    class RegForm(forms.Form):
        """
        用户注册表单
        """
        # 用户名
        username = forms.CharField(label='用户名',
            max_length=30,
            min_length=3,
            widget=forms.TextInput(
                attrs={'class': 'form-control', 'placeholder': '请输入用户名'}))
    
        # 邮箱
        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': '再输入依次密码'}))

      其中包含了一些属性设置,用来规范表单的显示。定义好表单之后,除了表单自动验证的部分外,还需要另外手动添加对字段的验证,如用户名,邮箱是否会与数据库已有的用户重复,还有第二次输入的密码与第一次输入的密码是否一致,以确保用户输入了正确的密码,所以还需在RegForm类中加入一些方法。

    def clean_username(self):
        """
        清洗输入的用户名
        :return: 清洗后的用户名
        """
        username = self.cleaned_data['username']
        if User.objects.filter(username=username).exists():
            raise forms.ValidationError('用户名已存在')
        return username
    
    def clean_email(self):
        """
        清洗输入的邮箱
        :return: 清洗后的邮箱
        """
        email = self.cleaned_data['email']
        if User.objects.filter(email=email).exists():
            raise forms.ValidationError('邮箱已存在')
        return email
    
    def clean_password_again(self):
        """
        清洗第二次输入的密码
        :return: 输入一致的密码
        """
        password = self.cleaned_data['password']
        password_again = self.cleaned_data['password_again']
    
        if password != password_again:
            raise forms.ValidationError('两次输入的密码不一致')
        return password

      其中forms.ValidationError是抛出表单错误的信息,在views.py中添加用户注册的处理,常用的Forms API:Working with forms

    from django.shortcuts import redirect, render
    from django.contrib import auth  # auth模块是Django提供的标准权限管理系统,可以提供用户身份认证, 用户组和权限管理。
    from django.urls import reverse    # 反向解析
    from django.contrib.auth.models import User
    from .forms import LoginForm, RegForm
    
    def register(request):
        """
        用户注册功能相关处理
        :param request: 请求对象
        :return: 注册成功返回首页,失败返回注册表单
        """
        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('blog:home')))
    
            '''
                # 第二种注册方法
                user = User()
                user.username = username
                user.email = email
                user.set_password(password)
                user.save()
    
            '''
    
        # 验证失败
        else:
            # login_form对象会自动创建表单
            reg_form = RegForm()
    
        context = {'reg_form': reg_form}
        return render(request, 'user/register.html', context)
    注册页面如下
    
    <div class="col-xs-11 col-sm-5 col-lg-4 col-sm-offset-4 blog-border side-info">
        <h4>欢迎注册</h4>
        <form action="" method="POST">{% csrf_token %}
    
            {% for field in reg_form %}
                {# label去冒号 #}
                <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>
                {# <span>用户名:</span> #}
                {# <input type="text" name="username"> #}
                {# <span>密码:</span> #}
                {# <input type="password" name="password"> #}
                <span style="font-weight: bold;">已有帐号?<a style="color: #337ab7;" href="{% url 'user:login' %}">点击登录</a></span>
            <input class="btn btn-primary pull-right" style="margin-bottom: 0.5em" type="submit" value="注册">
        </form>
        {% if user.is_authenticated %}
            <script type="text/javascript">
                window.location.href = '/';
            </script>
        {% else %}
    
        {% endif %}
    </div>

      最后在urls.py添加

    url(r'^register/', views.register, name='register'),

    三、用户登录

      与RegForm类似,需要用户名和密码,少了一些验证,只要判断在用户表中是否含有这个用户名。

    from django import forms  # django表单功能
    from django.contrib import auth
    from django.contrib.auth.models import User
    
    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': '请输入密码'}))
    
        def clean(self):
            """
            清洗输入不合格的表单
            :return: 清洗后的数据
            """
            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

      用户登录的视图处理。

    from django.shortcuts import redirect, render
    from django.contrib import auth  # auth模块是Django提供的标准权限管理系统,可以提供用户身份认证, 用户组和权限管理。
    from django.urls import reverse    # 反向解析
    from .forms import LoginForm
    
    def login(request):
        """
        用户登录逻辑处理
        :param request:
        :return: 登录视图
        """
        if request.method == 'POST':
            login_form = LoginForm(request.POST)
            # 判断是否有效
            # 验证通过
            if login_form.is_valid():
                # cleaned_data是一个字典,包含了字段的信息
                # 表示清理过或者整理过的数据,比较干净的数据
                # username = login_form.cleaned_data['username']
                # password = login_form.cleaned_data['password']
                # user = auth.authenticate(username=username, password=password)
                # 判断用户是否存在
                # if user is not None:
                user = login_form.cleaned_data['user']
                auth.login(request, user)
                # 如果没有获取到源页面就返回到首页
                referer = request.GET.get('from', reverse('blog:blog'))
                return redirect(referer)
    
        # 验证失败
        else:
            # login_form对象会自动创建表单
            login_form = LoginForm()
    
        context = {'login_form': login_form}
        return render(request, 'user/login.html', context)

      创建视图模板

    <div class="col-xs-11 col-sm-5 col-lg-4 col-sm-offset-4 blog-border side-info">
        <h4>用户登录</h4>
    
         <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>
                {# <span>用户名:</span> #}
                {# <input type="text" name="username"> #}
                {# <span>密码:</span> #}
                {# <input type="password" name="password"> #}
                <span style="font-weight: bold;">没有帐号?<a style="color: #337ab7;" href="{% url 'user:register' %}">点击注册</a></span>
                <input class="btn btn-primary pull-right" style="margin-bottom: 0.5em" type="submit" value="登录">
         </form>
    
        {% if user.is_authenticated %}
            <script type="text/javascript">
                window.location.href = '/';
            </script>
        {% else %}
        {% endif %}
    </div>

      在url.py添加

    url(r'^login/', views.login, name='login'),

    ​  还可以使用如下方法显示用户信息

    <p>加入时间:{{ user.date_joined }}</p>
    <p>上次登录时间:{{ user.last_login}}</p>

      原文出处:https://jzfblog.com/detail/105,文章的更新编辑以此链接为准。欢迎关注源站文章!

  • 相关阅读:
    docker部署mysql
    docker安装nginx
    Linux查看日志-grep
    linux系统常用命令
    python爬虫
    unittest中常用的assert语句
    Linux 监控tcp连接数及状态
    linux top命令查看内存及多核CPU的使用讲述
    jmeter的时间戳函数使用
    influxdb基本SQL操作2
  • 原文地址:https://www.cnblogs.com/djcoder/p/10871286.html
Copyright © 2020-2023  润新知