热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:五用django2.0来开发实现会员注册功能

本文由编程笔记#小编为大家整理,主要介绍了五用django2.0来开发实现会员注册功能相关的知识,希望对你有一定的参考价值。上一节我们完成了会员功能的后台管理,这一节我们需
本文由编程笔记#小编为大家整理,主要介绍了五 用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/‘, views.list),
]

这种应该用会比较多一些, 指定这个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[0-9]{4})/$‘, views.year_archive),
]

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

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

urlpatterns = [
re_path(r‘^comments/(?:page-(?Pd+)/)?$‘, 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 = "It is now %s." % 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对象

常用的属性如下























































属性说明
schemehttp 或 https
body请求的主体
path请求的路径 account/register/
path_info请求的路径
method请求方法GET,POST
encoding编码类型
content_typeheader头 的Content-Type
COOKIESCOOKIE信息
FILES表单的file字段上传的文件信息
METAheader头信息
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 %}










{% block body %} {% endblock %}





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 %}




{% csrf_token %}

{{ form.account}}


{{ form.password}}


{{ form.rep_password}}


{{ form.email}}


{{ form.phone}}





{% endblock %}

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

打开浏览器, 我们可以看一下效果
技术分享图片

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


推荐阅读
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • switch语句的一些用法及注意事项
    本文介绍了使用switch语句时的一些用法和注意事项,包括如何实现"fall through"、default语句的作用、在case语句中定义变量时可能出现的问题以及解决方法。同时也提到了C#严格控制switch分支不允许贯穿的规定。通过本文的介绍,读者可以更好地理解和使用switch语句。 ... [详细]
  • 在开发app时,使用了butterknife后,在androidStudio打包apk时可能会遇到报错。为了解决这个问题,可以通过打开proguard-rules.pro文件进行代码混淆来解决。本文介绍了具体的混淆代码和方法。 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
author-avatar
手机用户2502914971
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有