一步一步理解 python web 框架,才不会从入门到放弃 -- 简单登录页面

Posted 守护窗明守护爱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一步一步理解 python web 框架,才不会从入门到放弃 -- 简单登录页面相关的知识,希望对你有一定的参考价值。

上一节,我们基本了解了 Django 的一些配置,这一节,我们将通过一个简单的登录页面,进一步学习 Django 的使用。

新建项目

首先,新建一个 Django 项目,记得别弄错了哦。

settings 中静态文件、templates 路径配置

这里我们已经写好了登录页面(点我下载 密码:abh5),但是这一个登录页面不单只是一个 HTML 文件,还有一些静态文件。我们上一次已经说过了,想要在 HTML 中引进静态文件的话,需要在 settings 中配置静态文件夹。login.html 放在 templates 目录下,也需要在 settings 中配置 templates 文件夹。配置完成后如下图。

"""
Django settings for mysite project.

Generated by \'django-admin startproject\' using Django 2.0.5.

For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = \'-3+5fklj6_ard3d!^66n9=a^6p!v381pvm6r6h=c#84w%nzm1f\'

# SECURITY WARNING: don\'t run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    \'django.contrib.admin\',
    \'django.contrib.auth\',
    \'django.contrib.contenttypes\',
    \'django.contrib.sessions\',
    \'django.contrib.messages\',
    \'django.contrib.staticfiles\',
]

MIDDLEWARE = [
    \'django.middleware.security.SecurityMiddleware\',
    \'django.contrib.sessions.middleware.SessionMiddleware\',
    \'django.middleware.common.CommonMiddleware\',
    \'django.middleware.csrf.CsrfViewMiddleware\',
    \'django.contrib.auth.middleware.AuthenticationMiddleware\',
    \'django.contrib.messages.middleware.MessageMiddleware\',
    \'django.middleware.clickjacking.XFrameOptionsMiddleware\',
]

ROOT_URLCONF = \'mysite.urls\'

TEMPLATES = [
    {
        \'BACKEND\': \'django.template.backends.django.DjangoTemplates\',
        \'DIRS\': [os.path.join(BASE_DIR, \'templates\')]
        ,
        \'APP_DIRS\': True,
        \'OPTIONS\': {
            \'context_processors\': [
                \'django.template.context_processors.debug\',
                \'django.template.context_processors.request\',
                \'django.contrib.auth.context_processors.auth\',
                \'django.contrib.messages.context_processors.messages\',
            ],
        },
    },
]

WSGI_APPLICATION = \'mysite.wsgi.application\'


# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases

DATABASES = {
    \'default\': {
        \'ENGINE\': \'django.db.backends.sqlite3\',
        \'NAME\': os.path.join(BASE_DIR, \'db.sqlite3\'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        \'NAME\': \'django.contrib.auth.password_validation.UserAttributeSimilarityValidator\',
    },
    {
        \'NAME\': \'django.contrib.auth.password_validation.MinimumLengthValidator\',
    },
    {
        \'NAME\': \'django.contrib.auth.password_validation.CommonPasswordValidator\',
    },
    {
        \'NAME\': \'django.contrib.auth.password_validation.NumericPasswordValidator\',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/

LANGUAGE_CODE = \'en-us\'

TIME_ZONE = \'UTC\'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/

STATIC_URL = \'/static/\'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, \'static\'),
]
settings.py

逻辑及 url 规划

我们想要浏览器能够找到这一个页面,首先要给它配置一个 url。

urls.py 中放的是函数与路径的对应关系。但是函数不应该放在 urls.py 中,应该新建一个 views.py ,专门用来写函数逻辑。

这里,我们在 views.py 中定义一个 login 函数,用来收到请求后返回 login.html 页面。要返回一个 HTML  页面,我们就可以选择导入 render 模块,render 模块可以方便地返回浏览器请求,HTML 页面,还有我们想要返回的参数。

from django.shortcuts import render


def login(request):
    return render(request, \'login.html\')
views.py

写好逻辑处理函数之后,我们就来写函数与路径的对应关系,也就是 url 。

from django.conf.urls import url

from .views import login

urlpatterns = [
    url(r\'^login/$\', login),
]
urls.py

此时的项目目录应该如下图。

登录页面配置

我们在 login.html 中通过一个 form 表单,完成用户账号密码的输入和传送。

form 表单 action 属性表示输入往哪里送,往哪个 url 送。method 属性是方法,一般都设置成 post。

这里,我们先设置 action="/baobao/" method="post",也就是专门写一个名为 baobao 的函数,用以获取用户提交的数据,做是否登录成功的判断。

在 baobao 函数中,我们打印了浏览器 form post 过来的数据,然后返回一个 \'O98K\' 到页面显示 (#^.^#)

from django.conf.urls import url

from .views import login, baobao

urlpatterns = [
    url(r\'^login/$\', login),
    url(r\'^baobao/$\', baobao),
]
urls.py
from django.shortcuts import render, HttpResponse


def login(request):
    return render(request, \'login.html\')


def baobao(request):
    # 获取用户提交的数据,做是否登录成功的判断
    email = request.POST
    print(request.POST)
    return HttpResponse(\'O98K\')
views.py
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/fontawesome/css/font-awesome.min.css">
    <title>mysite-登录页面</title>
    <style>
        body {
            background-color: #eee;
        }
    </style>
</head>
<body>

<div class="container">
    <div class="row">
        <div class="col-md-4 col-md-offset-4" style="margin-top: 100px">
            <h1 class="text-center">请登录</h1>
            <form class="form-horizontal" action="/login/" method="post">
                <div class="form-group">
                    <label for="inputEmail3" class="col-sm-2 control-label"></label>
                    <div class="input-group col-sm-8">
                         <span class="input-group-addon"><i class="fa fa-envelope-o fa-fw"></i></span>
                        <input type="email" name="email" class="form-control" id="inputEmail3" placeholder="Email">
                    </div>
                </div>
                <div class="form-group">
                    <label for="inputPassword3" class="col-sm-2 control-label"></label>
                    <div class="input-group col-sm-8">
                        <span class="input-group-addon"><i class="fa fa-key fa-fw"></i></span>
                        <input type="password" name="pwd" class="form-control" id="inputPassword3" placeholder="Password">
                    </div>
                </div>
                <div class="form-group">
                    <div class="input-group col-sm-offset-2 col-sm-8">
                        <div class="checkbox">
                            <label>
                                <input type="checkbox"> 记住我
                            </label>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="input-group col-sm-offset-2 col-sm-8">
                        <button type="submit" class="btn btn-primary btn-block">登录</button>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>
</body>
</html>
login.html

启动项目,在浏览器输入 http://127.0.0.1:8000/login/,回车,顺利出现了我们的登录页面。

一脸兴奋,输入随便一个邮箱、密码,点击登录。什么?怎么提示错误了!!!

你确定你输入的是邮箱地址吗(*/ω\*).....

这一个提示,是 bootstrap 前端框架帮我们做的,在前端就进行了一次简单的表单验证。boostrap 是什么?你现在姑且把它当成是一个前端框架,我们以后再讲。

初涉 CSRF

再一次,输入正确的邮箱地址,密码,点击登录。Forbidden?这是什么鬼???

可以看到,url 已经成功跳转到 baobao 了,不过页面却显示 Forbidden。下面还有一行 CSRF verification failed. Request aborted. 这一个是 Django 自带的 CSRF 防范机制。CSRF 是什么?某度百科有言:“CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。”(可以看出,我们的 Django 框架,可是相当的严谨和方便。)

那么,这里我们应该怎么做呢?我们只需要在 form 表单标签内部加上一句 {% csrf_token %} 即可。

此时的 login.html 应为

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/fontawesome/css/font-awesome.min.css">
    <title>mysite-登录页面</title>
    <style>
        body {
            background-color: #eee;
        }
    </style>
</head>
<body>

<div class="container">
    <div class="row">
        <div class="col-md-4 col-md-offset-4" style="margin-top: 100px">
            <h1 class="text-center">请登录</h1>
            <form class="form-horizontal" action="/login/" method="post">
                <div class="form-group">
                    <label for="inputEmail3" class="col-sm-2 control-label"></label>
                    <div class="input-group col-sm-8">
                         <span class="input-group-addon"><i class="fa fa-envelope-o fa-fw"></i></span>
                        <input type="email" name="email" class="form-control" id="inputEmail3" placeholder="Email">
                    </div>
                </div>
                <div class="form-group">
                    <label for="inputPassword3" class="col-sm-2 control-label"></label>
                    <div class="input-group col-sm-8">
                        <span class="input-group-addon"><i class="fa fa-key fa-fw"></i></span>
                        <input type="password" name="pwd" class="form-control" id="inputPassword3" placeholder="Password">
                    </div>
                </div>
                <div class="form-group">
                    <div class="input-group col-sm-offset-2 col-sm-8">
                        <div class="checkbox">
                            <label>
                                <input type="checkbox"> 记住我
                            </label>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="input-group col-sm-offset-2 col-sm-8">
                        <button type="submit" class="btn btn-primary btn-block">登录</button>
                    </div>
                </div>
                {% csrf_token %}
            </form>
        </div>
    </div>
</div>
</body>
</html>
login.html

重启项目,再次回到 login 页面,输入,登录。终于看到我们想要的 ‘O98K’ 了。 o(╥﹏╥)o

提取数据及账号密码验证

而且可以在 pycharm 的 Terminal 中看到打印出来的数据。(我是在 pycharm 的 Terminal 中启动项目的,所以可以在这里看到打印的数据)

\'email\' 对应的是我们输入的邮箱。\'pwd\' 对应的是我们输入的密码。\'email\' 和 \'pwd\' 是在哪里定义的呢?是我们在 login.html 的 form 的 input 中定义的 name 属性。要想给服务器传数据,必须给它们起一个 name。

既然可以获取到浏览器传过来的数据了,我们就可以在 baobao 函数中取出这些数据,做邮箱、密码的验证。

from django.shortcuts import render, HttpResponse


def login(request):
    return render(request, \'login.html\')


def baobao(request):
    # 获取用户提交的数据,做是否登录成功的判断分别
    # 取出邮箱和密码进行验证
    email = request.POST.get(\'email\', None)
    pwd = request.POST.get(\'pwd\', None)
    if email == \'123@qq.com\' and pwd == \'abc123\':
        # 登录成功
        return HttpResponse(\'登录成功\')
    else:
        # 登录失败
        return HttpResponse(\'登录失败\')
views.py

输入错误的邮箱和密码进行登录,再输入正确的邮箱和密码进行登录。可以看到,我们想要的逻辑都能够正确运行。

逻辑及 url 优化

整理一下逻辑

首先,启动项目之后,在浏览器输入 http://127.0.0.1:8000/login/,浏览器就会给服务器发送一个 GET 请求,服务

以上是关于一步一步理解 python web 框架,才不会从入门到放弃 -- 简单登录页面的主要内容,如果未能解决你的问题,请参考以下文章

读懂源码:一步一步实现一个 Vue

python webdriver 一步一步搭建数据驱动测试框架的过程和总结

Python飞机大战项目终篇(一步一步实现---最全笔记)

从0開始Tornado建站整体设计

一步一步实现web程序信息管理系统之二----后台框架实现跳转登陆页面

一步一步实现web程序信息管理系统之二----后台框架实现跳转登陆页面