Django No. 29-One of the form submission methods: post request (register/login/change password)

1. The purpose of writing this blog

Mainly record the common and specific usage of form submission method post;

Because most of the company project interfaces in Xiamen use the post form submission method, just the registration interface/login interface/change login password interface/forgot password interface form submission methods are basically post, so this blog will take the registration interface/ Login interface/change login password interface These three interfaces are connected in series to explain the complete operation process;

The steps of the complete operation process we want to achieve are roughly as follows:

  1. The user enters the [Registration Page] by visiting the [Registration Address];
  2. When the user registers on the [Registration Page], the field value rule of each submitted field will be verified: if the registration fails, it will stay on the [Registration Page] and give the corresponding error message; after the registration is successful, it will jump to the [Registration Success Prompt Page 】;
  3. The user clicks on the [Return to a link to the login page] on the [Registration Success Prompt Page], and it will be redirected to the [Login Page];
  4. When the user logs in on the [Login Page], the field value rules of each submitted field will be verified: if the login fails, it will stay on the [Login Page] and give the corresponding error message; after the login is successful, it will jump to the [Background Home Page] ;
  5. The user clicks on the [Logout page of a link] in the [Background Home Page], and it will be redirected to the [Login Page];
  6. The user logs in on the [Login Page], and after the login is successful, it will be redirected to the [Background Home Page];
  7. The user clicks on the [a link to modify the login password] on the [Background Home Page], and it will be redirected to the [Modify Login Password Page];
  8. The user will verify the field value of each submitted field in the [Modify Login Password Page]. Rules: If the login password fails to be modified, it will stay on the [Modify Login Password Page] and give the corresponding error message; after the login password is successfully modified, it will jump Go to [Modify login password success page];
  9. The user clicks on the [Return to a link to the back-end home page] on the [Change login password success page], and it will be redirected to the [Back-end home page];

detail:

  1. The correct operation is to carry out the corresponding process operation according to the specific requirements rules written in the product documentation;
  2. To allow users to access a specified html page after entering a specified url address in the browser, combined with django’s MTV idea, the main logic is roughly implemented like this: first create an html page, then create a view function, and then create A url matching rule, and finally debugging;
  3. The respective functions and usage scenarios of the form submission methods get and post can be understood on Baidu by yourself;

The complete operation process can be seen in the following content;

 

Second, the complete operation process

1. The first step: add relevant html pages

According to this folder hierarchy, add two new folders [index] and [user], and add 5 html pages;

 1.1. Add a new [index.html]

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>后台主页</title>

</head>

<body>



<p>

    这是后台主页,您可以进行任意业务操作!

    <br>

    <br>

    <a href="{% url 'urlName_of_login' %}">点击这个链接,可以成功退出登录并跳转到登录页面</a>

    <br>

    <a href="{% url 'urlName_of_update_password' %}">点击这个链接,可以跳转到修改登录密码页面</a>

</p>





</body>

</html>

 1.2. Add a new [login.html]

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>登录页面</title>

</head>

<body>

<h1>欢迎登录!</h1>

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

    {% csrf_token %}

    <p>

        用户名:<label for="id_username"></label><input type="text" id="id_username" name="username" required="required">

        * {
   
   { error_of_username }}

    </p>

    <p>

        密码:<label for="id_password"></label><input type="text" id="id_password" name="password" required="required">

        * {
   
   { error_of_password }}

    </p>



    <p>

        <input type="submit" value="登录">

    </p>

</form>



</body>

</html>

 1.3. Add a new [register_html.html]

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>注册页面</title>

</head>



<body>

<h1>新用户注册!</h1>

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

    {% csrf_token %}

    <p>

        用户名:<label for="id_username"></label><input type="text" id="id_username" name="username" required="required">

        * {
   
   { rename }}

    </p>

    <p>

        密码:<label for="id_password"></label><input type="text" id="id_password" name="password" required="required"> *

    </p>

    <p>

        注册邮箱:<label for="id_mail"></label><input type="text" id="id_mail" name="mail">

    </p>

    <p>

        <input type="submit" value="提交注册信息">

    </p>

</form>



</body>

</html>

 1.4. Add a new [register_success_html.html]

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>注册成功页面</title>

</head>

<body>



<p>

    亲爱的用户,恭喜您注册成功!

    <br>

    <br>

    <a href="{% url 'urlName_of_login' %}">点击这个链接,可以跳转到登录页面</a>



</p>





</body>

</html>

1.5. Add a new [update_password_html.html]

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>修改登录密码页面</title>

</head>

<body>

<h1>请修改您的登录密码!</h1>

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

    {% csrf_token %}

    <p>

        用户名:<label for="id_username"></label><input type="text" id="id_username" name="username" required="required">

        * {
   
   { error_of_username }}

    </p>

    <p>

        旧密码:<label for="id_old_password"></label><input type="text" id="id_old_password" name="old_password"

                                                        required="required"> * {
   
   { error_of_old_password }}

    </p>

    <p>

        新密码:<label for="id_new_password"></label><input type="text" id="id_new_password" name="new_password"

                                                        required="required"> * {
   
   { error_of_new_password }}

    </p>



    <p>

        <input type="submit" value="确定">

    </p>

</form>



</body>

</html>

1.6. Add a new [update_password_success_html.html]

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>修改登录密码成功页面</title>

</head>

<body>

<p>

    亲爱的用户,恭喜您修改登录密码成功!

    <br>

    <br>

    <a href="{% url 'urlName_of_index' %}">点击这个链接,可以跳转到后台主页页面</a>

</p>

</body>

</html>

 

2. Step 2: Add related view functions

According to this folder hierarchy, a new folder [views_of_hello] is added, and 2 py files storing view functions are added. The two py files are [indexViews.py] and [userViews.py];

2.1. Add a new [indexViews.py]

#!/usr/bin/python

# -*- coding:utf-8 -*-



"""""""""""""""""""""""""""""""""

@file: userViews.py

@author: lucas

@createTime: 2021/3/9 5:53 下午

@Function: 存储后台主页的所有视图函数

"""""""""""""""""""""""""""""""""



# 用户登录成功后跳转到的后台主页对应的视图函数

from django.shortcuts import render





def index(request):

    return render(request, 'index/index.html')

 

2.2. Add a new [userViews.py]

#!/usr/bin/python

# -*- coding:utf-8 -*-



"""""""""""""""""""""""""""""""""

@file: userViews.py

@author: lucas

@createTime: 2021/3/9 5:53 下午

@Function: 存储后台主页的所有视图函数

"""""""""""""""""""""""""""""""""



from django.shortcuts import render

from django.http import HttpResponse, Http404, JsonResponse

from hello.models import User

from django.contrib.auth.hashers import make_password, check_password

import re





def register(request):

    '''用户注册页面对应的视图函数'''

    res = ''

    if request.method == 'POST':

        username = request.POST.get('username')  # 用户名

        password = request.POST.get('password')  # 密码

        mail = request.POST.get('mail')  # 注册邮箱

        # 先查询数据库是否已经有这个用户名

        user_list = User.objects.filter(user_name=username)

        if len(user_list) != 0 or user_list:

            # 如果这个用户名已存在,就给个提示

            res = '用户名为【%s】的用户已被注册!' % username

            return render(request, 'user/register.html', {"rename": res})

        # 如果这个用户名不存在即还没被注册,就执行新增数据到数据表的操作(涉及到sql新增语句)

        else:

            # 第一种写法(推荐以后都用这种写法)

            user = User()

            user.user_name = username

            user.user_psw = make_password(password)

            user.user_email = mail

            user.save()



            # 第二种写法(不推荐)

            # user = User(user_name=username,user_psw=password,user_email=mail)

            # user.save()



            return render(request, 'user/register_success.html')

    return render(request, "user/register.html")





def register_success(request):

    '''用户注册成功后跳转到的注册成功页面对应的视图函数'''

    return render(request, 'user/register_success.html')





def login(request):

    '''登录页面对应的视图函数'''

    # 第1步:判断请求方式是不是post

    if request.method == 'POST':

        # 第2歩:获取登录页面传给这个视图函数的每个提交字段的字段值

        username = request.POST.get("username")

        password = request.POST.get("password")

        # 第3步:查询用户名是否存在:如果不存在则返回一个用户名相关的错误提示语

        user_list_1 = User.objects.filter(user_name=username)

        if len(user_list_1) == 0:

            error_of_username = '用户名为【%s】的用户不存在,请重新输入!' % username

            return render(request, 'user/login.html', {"error_of_username": error_of_username})



        # 第4步:校验密码:如果校验不通过则返回一个密码相关的错误提示语;如果校验通过则允许登录成功并跳转到后台主页;

        user_list_2 = User.objects.filter(user_name=username).first()

        is_password_true = check_password(password, user_list_2.user_psw)

        if is_password_true:

            return render(request, 'index/index.html')

        else:

            error_of_password = '密码错误,请重新输入!'

            return render(request, 'user/login.html', {"error_of_password": error_of_password})



    else:

        return render(request, "user/login.html")





def update_password(request):

    '''修改登录密码页面对应的视图函数'''

    if request.method == 'GET':

        return render(request, "user/update_password.html")



    if request.method == 'POST':

        username = request.POST.get("username")  # 用户名

        old_password = request.POST.get("old_password")  # 旧密码

        new_password = request.POST.get("new_password")  # 旧密码



        if len(username) > 10:

            error_of_username = '用户名的长度不能超过10'

            # data = {}

            # data["code"] = 100

            # data["success"] = False

            # data["error_of_username"] = error_of_username

            # return JsonResponse(data,json_dumps_params={"ensure_ascii":False})    # 返回一个json串

            return render(request, "user/update_password.html", {"error_of_username": error_of_username})

        if len(old_password) > 10:

            error_of_old_password = '旧密码的长度不能超过10'

            return render(request, "user/update_password.html", {"error_of_old_password": error_of_old_password})

        if len(new_password) > 10:

            error_of_new_password = '新密码的长度不能超过10'

            return render(request, "user/update_password.html", {"error_of_new_password": error_of_new_password})

        if old_password == new_password:

            error_of_new_password = '新密码不能跟旧密码一样'

            return render(request, "user/update_password.html", {"error_of_new_password": error_of_new_password})



        regex = "^[0-9a-zA-Z_]{1,}$"

        if not re.search(regex, old_password):

            error_of_old_password = '旧密码的值只能由数字和英文字母和下划线组成'

            return render(request, "user/update_password.html", {"error_of_old_password": error_of_old_password})

        if not re.search(regex, new_password):

            error_of_new_password = '新密码的值只能由数字和英文字母和下划线组成'

            return render(request, "user/update_password.html", {"error_of_new_password": error_of_new_password})



        user_list1 = User.objects.filter(user_name=username).values()

        if len(user_list1) == 0:

            error_of_username = '不存在用户名为【%s】的用户' % username

            return render(request, "user/update_password.html", {"error_of_username": error_of_username})



        user_list_2 = User.objects.filter(user_name=username).first()

        is_password_true = check_password(old_password, user_list_2.user_psw)



        if not is_password_true:

            error_of_old_password = '旧密码错误,请重新输入'

            return render(request, "user/update_password.html", {"error_of_old_password": error_of_old_password})

        else:

            user = User.objects.get(user_name=username)

            user.user_psw = make_password(new_password)

            user.save()

            # return HttpResponse("密码更新成功!")

            return render(request, "user/update_password_success.html")

Attached:

Related knowledge points:

The role of template tag [{% csrf_token %}]

The role of the template tag [{% csrf_token %}]: If the attribute value of the attribute action in the form tag of an html page is post, the template tag [{% csrf_token %}] must be added to the content of the form tag. Because it can prevent cross-site forged requests;

CSRF: Cross Site Request Forgery (full English name), cross-site forgery request (full Chinese name).

For example, there is a link to your website on a malicious website. If a user has logged in to the malicious website, when the user clicks on the link on the malicious website, it will be sent to When your website sends a request, your website will think that the request was sent by the user. In fact, the request was forged by the malicious website.

When Django responds to a request from a client for the first time, it will randomly generate a token on the server side and place this token in the cookie. Then every POST request will bring this token, so as to avoid CSRF attacks.

The specific content of CSRF roughly has these points (just need to understand the concept):

  1. In the cookie of the returned HTTP response, django will add a csrftoken field for you, the value of which is an automatically generated token;
  2. If the attribute value of the attribute action in the form tag of an html page is post, it must include a csrfmiddlewaretoken field (just add this template tag [{% csrf_token %}] to the content of the form tag, and django will automatically help you generate); 
  3. Before processing the POST request, django will verify whether the value of the csrftoken field in the cookie of the request is the same as the value of the csrfmiddlewaretoken field in the submitted form: if they are the same, it indicates that this is a legitimate request; otherwise, the request may be From someone else's csrf attack, return [403 Forbidden];
  4. In all ajax POST requests, add an [X-CSRFTOKEN header] whose value is the field value of the csrftoken field in the cookie;

2.3. Step 3: Add url matching rules

Add url matching rules in [helloworld/helloworld/urls.py]

  #这部分是针对数据表user的所有url匹配规则的汇总=====================================================

     url(r"^user_register_001/$",userViews.register),

     url(r"^user_register_success_001/$",userViews.register_success),

     url(r"^user_login_001/$",userViews.login,name="urlName_of_login"),

     url(r"^user_update_password_001/$",userViews.update_password,name="urlName_of_update_password"),





    #这部分是针对后台主页的所有url匹配规则的汇总=====================================================

     url(r"^index_001/$",indexViews.index, name="urlName_of_index"),

 

2.4 Step 4: There is a detail change here: the length of the original database password field is too small

 

2.5. Step 4: Restart the service

2.6. Step 5: Perform related operations on any browser

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/LYX_WIN/article/details/114777257