五 【用django2.0来开发】实现会员注册功能

上一节我们完成了会员功能的后台管理, 这一节我们需要完成会员注册功能, 涉及到以下几个模块

  1. URL配置
  2. views视图模块
  3. 模板
  4. Request/Response对象的使用

项目地址:https://gitee.com/ccnv07/django_example

URL路由配置

django是通过项目的urls.py文件来定义网站的url路由, 在我们的项目中是cms/urls.py文件

django的基本访问流程

  1. 访问url时, 通过cms/urls.py中定义的url路由, 获取到要执行的视图函数或者类(保存在views.py)
  2. 将Request(请求对象)转发到指定的视图函数/类中, 执行视图函数/类的代码
  3. 通过模板渲染(没有模板则是其他的JsonResponse等资源对象), 将结果数据返回并输出到浏览器中

打开cms/urls.py文件

from django.contrib import admin
from django.urls import path
urlpatterns = [
    path(‘admin/‘, admin.site.urls),
]

urlpatterns是整个路由的一个list, 是django定义的固定名称

path函数
path(route, view, kwargs=None, name=None)
route: 指定访问的路由
view: 是指定访问的视图函数/类
name: 是指定这条路由的名称, 通过这个名称, 我们就可以生成一个可访问的url

默认的这一条路由, 就是定义了整个后台的访问url, 都是以admin/开头的url, django会将admin.site.urls中定义的路由都加载过来

比如我们之前做的后台管理功能, url就是:/admin/account/account/

路由route参数的格式

1. 固定字符串路由

这种路由是固定访问的url, 不会发生变化, 比如关于我的访问页面.

urlpatterns = [
    path(‘about/‘, views.about),
]

2. 带有变量的url路由, 比如我们访问指定栏目下的文章

urlpatterns = [
    path(‘list/<int:nav_id>‘, views.list),
]

这种应该用会比较多一些, <int:>指定这个nav_id必须是数字类型, 会执行类型强制转换, 而nav_id就是参数名, 通过以下的方式, 就可以访问到这个参数。

# views.py
def list(request, nav_id):
    pass

除了支持int, django的url路由也支持str,slug,uuid,path四种类型, 一般常用的也就是str和int

3. 正则表达式路由

from django.urls import path, re_path

from . import views

urlpatterns = [
    path(‘articles/2003/‘, views.special_case_2003),
    re_path(r‘^articles/(?P<year>[0-9]{4})/$‘, views.year_archive),
]

path函数定义的是普通的路由
re_path韩都定义正则路由, 参数完全一样

像上面这个例子中的re_path, 每个()中就是一个参数的定义, ?P说明这里定义的是一个参数, <year>是参数key, [0-9]{4}是正则表达式, $符代表路由结束, 不再往后匹配。
所以这个url可以匹配到articles/2018/ 这样的url

urlpatterns = [
    re_path(r‘^comments/(?:page-(?P<page_number>\d+)/)?$‘, comments),  # good
]

在这个例子中, ?: 代表是这是一个字符串的url, page-并不是一个参数
所以匹配的url是comments/page-1 的url

4. 包含其他的路由

from django.urls import include, path
urlpatterns = [
    path(‘account/‘, include(‘account.urls‘)),
]

include
include(module, namespace=None)
include(pattern_list)
include((pattern_list, app_namespace), namespace=None)

module: urlconf的模块
namespace: url入口的命名空间
pattern_list: 可以迭代的path()/re_path实例类
app_namespace: url入口的app的命名空间

之后会依次讲, 一般我们常见的也就是include(‘account.urls‘))这种方式, 会将account/urls.py中定义的url路由都加载进来
一下就是在account/urls.py中定义的路由

# account/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path(‘index/‘, views.index, name=‘account-index‘)
]

根据以上的路由规则, 我们可访问的url就是account/index/ 这个url

定义会员注册的路由

将模块路由文件加载进项目中

# cms/urls.py
import debug_toolbar
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
    path(‘admin/‘, admin.site.urls),
    path(‘account/‘, include(‘account.urls‘))
]

这样关于会员模块的url路由, 我们就都可以在account/urls.py文件中定义了。

在模块中定义url路由

创建account/urls.py文件

# account/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path(‘register/‘, views.register, name=‘account-register‘)
]

View视图模块

视图函数的定义

from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

每个视图函数都有一个固定的参数request, 这个是Request对象, 包含浏览器发起请求带的参数, 包括常见的url, post数据, 请求类型, header头等等。

然后视图函数的返回也必须是一个Reponse对象, 一般我们返回的都是html代码, 所以使用的是HttpResponse对象
有时候我们写的是接口, 使用的是JsonResponse对象

视图中最常用的函数

render 模板渲染函数

但是如果把html代码写在python文件中, 也太不好看了, 所以, 我们可以通过render函数来完成模板的渲染
render(request, template_name, context=None, content_type=None, status=None, using=None)

request: 是请求对象,
template_name: 模板文件名称
context: 要传递给模板文件的变量
content_type: 文档header头中Content-Type的类型
status: http响应码, 就是200, 301, 302, 400, 500那个
using: 要使用的模板引擎

from django.shortcuts import render

def my_view(request):
    # View code here...
    return render(request, ‘myapp/index.html‘, {
        ‘foo‘: ‘bar‘,
    }, content_type=‘application/xhtml+xml‘)

render会自动帮我们转换成HttpResponse对象, 所以也不需要再写一遍HttpResponse了

redirect 跳转函数

当会员注册完成后, 我们就需要自动跳转到会员中心页或者首页, 这时就得使用redirect函数来实现了
redirect(to, permanent=False, *args, **kwargs)

to: 要跳转的地址,
permanent: 是否永久跳转, 说白了就是301/302代码的区别, 不动301,302自行百度。

from django.shortcuts import redirect
def my_view(request):
    ...
    return redirect(‘/some/url/‘)

reverse Url路由转url函数

redirect完成url跳转时, 万一我定义的url都变了, 觉得以前定义的url太丑了, 太长了, 老板不喜欢了, 那不坑爹了么?那我不得满项目找url, 挨个改阿?
其实django已经想到这点了, 还记得我们在定义url路由时的name参数么?
通过reverse函数, 就可以将urls.py中定义的url路由转换为url了

reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
viewname: url路由的名称
urlconf: url路由的模块名, 默认是根模块, 也就是咱们的cms文件中的urls.py
args: 要传递给url路由的参数

视图中的Request和Response对象

一般发生请求后有两种资源, 一种是请求的资源,是浏览器发送给服务器的资源, 包括请求的url, 头, 传递的参数, cookie什么的。
还有一种是返回的资源, 就是服务器发送给浏览器的资源。

HttpRequest对象

常用的属性如下

属性 说明
scheme http 或 https
body 请求的主体
path 请求的路径 account/register/
path_info 请求的路径
method 请求方法GET,POST
encoding 编码类型
content_type header头 的Content-Type
COOKIES cookie信息
FILES 表单的file字段上传的文件信息
META header头信息
session 保存session信息, dict结构

常用的方法

方法 说明
get_host() 127.0.0.1:8000
get_port() 请求的端口
get_full_path() 请求的全路径
is_ajax() 是否ajax请求

HttpResponse对象

常用的属性

属性 说明
content 请求返回的资源内容
charset 编码
status_code 返回的http状态码
JsonResponse对象

JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs)

data: 要返回的json数据, 是dict结构
encoder: 数据的转码类, 一般不需要更改
json_dumps_params: json_dumps函数

针对我们的项目, 就可以在cms/utils.py(没有就创建)文件中定义一个通用的返回jsonResponse的函数,

from django.http import JsonResponse

def return_json(code = 0, message = ‘success‘, data = [], url=‘‘):
    return JsonResponse({
        ‘code‘: code,
        ‘url‘: url,
        ‘message‘: message,
    })

模板层说明

模板文件路径

默认模板文件路径会在模块名/templates中, 但是在一般的项目开发中, 都会把所有的模板放在一起, 所以我们需要重新定义模板的路径

# cms/settings.py
TEMPLATES = [
    {
        ‘BACKEND‘: ‘django.template.backends.django.DjangoTemplates‘,
        ‘DIRS‘: [
            # 将templates目录放在根目录
            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‘,
            ],
        },
    },
]

在settings.py 中TEMPLATES.DIRS中增加os.path.join(BASE_DIR, ‘templates‘), 模板文件的目录就变为了cms/templates

静态资源文件路径和访问url修改

静态文件路径同模板一样, 我们也需要修改到根目录下

# cms/settings.py
STATIC_URL = ‘/static/‘
STATICFILES_DIRS = (‘static‘, )

模板常用标签说明

一般模板的顶部、底部等很多地方都是一样的, 所以我们可以定义一个布局html页面, 将这些一样的地方提取出来放在一起

# templates/layout.html
{% load static %}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>{% block title %} {% endblock %}</title>
    <link rel="stylesheet" href="{% static ‘css/bootstrap.min.css‘%}">
</head>

<body>
    {% block body %} {% endblock %}
</body>
<script src="{% static ‘js/jquery.min.js‘ %}"></script>
<script src="{% static ‘js/bootstrap.min.js‘ %}"></script>
<script src="{% static ‘js/layer/layer.js‘ %}"></script>
<script src="{% static ‘js/utils.js‘ %}"></script>
</html>

load static 这个标签是指加载static模块, 只有加载了后, 才可以使用{% static %}来读取静态资源文件
block endblock 定义了不同的块, 并且为每个块进行命名
这样假设我定义了一个会员注册页

# templates/account/register.html
{% extends ‘layout.html‘ %}
{% block title %} 注册 {% endblock %}

那么, layout.html中的{% block title %} {% endblock %}就会被替换成"注册"

extends 标签, 指定的就是加载layout.html这个布局页面

定义注册会员的表单

我们先在account/forms.py中定义表单RegisterForm, 因为之前已经定义了一个AccountForm, 所以我们这个表单可以直接继承AccountForm

class RegisterForm(AccountForm):
    # 设置场景是新增用户
    scene = ‘insert‘
    class Meta(AccountForm.Meta):
        # 使用自定义的Form, 就必须指定fields or exclude属性, 否则报错
        # 注册的时候我们不需要设置status, 字段, 所以排除掉。
        fields = (‘account‘, ‘password‘, ‘email‘, ‘phone‘)

注册的时候, 一般需要输入重复密码, 所以我们多定义一个rep_password字段

class RegisterForm(AccountForm):
    ... 忽略代码
     rep_password = forms.CharField(
        label=‘重复密码‘,
        required=True,
        error_messages={‘required‘: ‘请再次输入密码‘},
        widget=forms.PasswordInput())

    def clean_rep_password(self):
        # 验证两次输入的密码是否一致
        # 因为在clean_password方法中, 已经加密了cleaned_data[‘password‘], 所以这里只能取data[‘password‘]
        if self.data[‘password‘] != self.cleaned_data[‘rep_password‘]:
            raise ValidationError(‘两次输入的密码不一致‘)

        return self.cleaned_data[‘rep_password‘]

定义视图

在视图中, 如果是GET请求, 我们则渲染表单, 如果是POST请求, 我们就执行注册用户

GET 请求的代码

from django.shortcuts import render
from .forms import RegisterForm

def register(request):
    form = RegisterForm()
        return render(request, ‘account/register.html‘, {‘form‘: form})

编写模板代码

我使用的是bootstrap前端框架, 大家可以下载了放在static文件夹中, 修正layout.html中的路径

首先我们先将layout.html布局模板加载进来

# templates/account/register.html
{% extends ‘layout.html‘ %}
{% block title %} 注册 {% endblock %}

然后在block body部分, 写入我们要渲染的表单

{% block body %}
<div class="container">
    <div class="row" style="width:500px">
        <form action="{% url ‘account-register‘%}" method="post" onsubmit="return post(this)">
            {% csrf_token %}
            <div class="form-group">
                <label for="{{ form.account.id_for_label}}">{{ form.account.label}}</label> {{ form.account}}
            </div>
            <div class="form-group">
                <label for="{{ form.password.id_for_label}}">{{ form.password.label}}</label> {{ form.password}}
            </div>
            <div class="form-group">
                <label for="{{ form.rep_password.id_for_label}}">{{ form.rep_password.label}}</label> {{ form.rep_password}}
            </div>
            <div class="form-group">
                <label for="{{ form.email.id_for_label}}">{{ form.email.label}}</label> {{ form.email}}
            </div>
            <div class="form-group">
                <label for="{{ form.phone.id_for_label}}">{{ form.phone.label}}</label> {{ form.phone}}
            </div>
            <input type="submit" value="提交" class="btn btn-success">
        </form>
    </div>
</div>
{% endblock %}

很多地方基本都是一样的, {{ form.}} 中的form就是我们在view中传过来的form表单类
form.account_id_for_label: 就是input的类
{{ form.account.label}}: 是显示的表单字段的名称
{{ form.account}}: 会直接生成一段input的表单字段代码。

打开浏览器, 我们可以看一下效果

看起来样式还不错
现在, 我们就可以点击提交尝试一下了

原文地址:http://blog.51cto.com/a3147972/2311477

时间: 2024-10-14 10:58:15

五 【用django2.0来开发】实现会员注册功能的相关文章

【用django2.0来开发】 后台会员管理

[用django2.0来开发] 后台会员管理 项目地址:https://gitee.com/ccnv07/django_example这一篇主要是要完成django 后台的会员管理功能, 会涉及到model, ModelAdmin, admin, Form等多个方面, 所以会讲的比较细 创建会员模块 cd cms python manage.py startapp account python manage.py startapp 是创建一个模块 至于模块的定义, 每个人都有不同的看法, 有些是

一、【用django2.0来开发】 环境部署和初始化项目

一.[用django2.0来开发] 环境部署和初始化项目 发现网上没有什么比较好的django系列的教程, 所以打算写一整套教程来教会大家如何使用django2.0 整个教程都会围绕一个开发一个项目来完成, 这一篇主要就是讲清楚整个环境以及初始化下项目, 以及一些开发中常见的操作项目地址:https://gitee.com/ccnv07/django_example 项目介绍 大概就是使用python开发一个cms系统, 和大家知道的dede,phpcms有些类似, 可以注册.登录.有会员系统.

四【用django2.0来开发】后台会员管理(二) ModelForm表单的使用方法以及数据验证

上一节我们讲完了ModelAdmin的使用, 但是在操作中也发现, 新增编辑会员时, 我们无法验证数据是否正确, 比如 用户名.手机号.邮箱都应该是唯一的 用户名和密码长度的验证 编辑用户信息时不填写密码则不更新密码, 填写了则更新密码 自定义验证不通过的文案... 这些要求, 我们就必须得使用自定义的表单来完成了 项目地址:https://gitee.com/ccnv07/django_example Form介绍 通过表单, 我们可以实现以下的功能 自定义字段的样式 类似的表单可以通过类继承

Yii入门指导(五):实战之“会员注册”

事情纠结多了反而不好..... 1,会员数据库表结构如下: 2,建立会员模型,位于:protected/modules/admin/models 目录下  <?php /**  * 用户表的模型  * @author koma  *  */ class User extends CActiveRecord { //声明非数据库字段 public $password2; public static function model($className = __CLASS__) { return pa

MVC会员注册

自从写了<数据库数据加密与解密>http://www.cnblogs.com/insus/p/3434735.html.其中也有提及Insus.NET将要在MVC应用程序中实现会员注册的功能.一段时间来,工作繁忙,这个星六还要值班.现在算是忙里偷闲,继续写MVC的程序.本次要实现会员注册功能,从最简单的入手.在数据库中,创建一张会员表[Member] 注意一下密码字段的数据类型,由于要把密码加密之后,它会转换为二进制.有关加密,可以参加文章开头的链接.接下来,完成注册的存储过程[dbo].[u

做项目学习Django2.0开发

课程详情可访问:项目学习django2.0.3 项目代码可加qq群:631575625 下载 原文地址:http://blog.51cto.com/13340781/2122185

Yii2.0中文开发向导——RBAC(基于角色的访问控制权限)表结构原理分析

这里有几个概念很重要,我简单用大白话说一下;权限:就是指用户是否可以执行哪些操作.如:小张可以发帖.回帖.浏览,小红只能回帖.浏览角色:就是上面说的一组操作的集合.如:高级会员有发帖.回帖.删贴.浏览的权限,普通会员只有回帖.浏览的权限.比如小张是高级会员,那么他就可以执行发帖.回帖.删贴.浏览.而小红是普通会员,所以它就只能回帖.浏览.另外角色还可以继承,中级会员除了普通会员的回帖.浏览功能外,还可以发帖.也就是说在普通会员的基础上又增加了一个发帖的权限.在Yii2.0中 yii\rbac:

10天学会phpWeChat——第十天:phpWeChat的会员注册、登录以及微信网页开发

通过前面的系列教程,我们系统的讲解了phpWeChat从视图端.控制器端到模型端的操作流程:熟悉了phpWeChat的目录结构:掌握了视图端模板如何创建一个丰富的表单和模型端如何操作数据库.这一切都是传统Web以及现代H5开发的核心. 我们今天进行<10天学会phpWeChat>教程的最后一讲,phpWeChat的微信网页开发.在这一讲里,我们将重点讲解在微信网页开发中几个常见参数的获取和一个微信扫一扫的实例. 一.微信网页开发中的几个重要参数(文档参考:https://mp.weixin.q

AMP+EPP3.0的开发环境配置

经过摸索,总结出下列Apache.MySQL.PHP.EPP.ZendDebugger的开发环境配置方法: 版本: Apache: Apache-httpd-2.2.25-win32-x86-no_ssl.msi MySQL:mysql-5.5.28-win32.zip PHP:php-5.3.28-Win32-VC9-x86.msi EPP:EPP3_Setup.rar ZendDebugger:ZendDebugger-20110410-cygwin_nt-i386.zip 一.先安装上述软