登录与注册系统
reference:http://www.liujiangblog.com/course/django/104
搭建项目环境
Pycharm创建虚拟环境
修改settings.py时区语言
创建login app
模型层
数据库模型设计
from django.db import models# Create your models here.class User(models.Model):gender = (('male', '男'),('female', '女'),)name = models.CharField(max_length=128, unique=True)password = models.CharField(max_length=256)email = models.EmailField(unique=True)sex = models.CharField(max_length=32, choices=gender, default='男')c_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') # 创建时间def __str__(self):return self.nameclass Meta:ordering = ['-c_time'] # 时间降序排列verbose_name = '用户'verbose_name_plural = '用户'
数据库后端
Django支持Mysql,SQLite,Oracle等,默认使用SQLite
注册app
创建记录和数据表
python manage.py makemigrationspython manage.py migrate
Admin后台
在admin中注册模型
# loginResgiter/settings.pyINSTALLED_APPS = ['django.contrib.admin', # 看这里'django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions', # 看这里'django.contrib.messages','django.contrib.staticfiles','login',]# login/admin.py 显示在admin后台from django.contrib import admin# Register your models here.from . import modelsadmin.site.register(models.User)
创建超级管理员
python manage.py createsuperuser
视图层+模板层
路由设计
访问逻辑
- 未登录人员,不论是访问index还是login和logout,全部跳转到login界面
- 已登录人员,访问login会自动跳转到index页面
- 已登录人员,不允许直接访问register页面,需先logout
- 登出后,自动跳转到login界面
一级路由
loginRegister/urls.pyfrom django.contrib import adminfrom django.urls import pathfrom login import viewsurlpatterns = [path('admin/', admin.site.urls),path('index/', views.index),path('login/', views.login),path('register/', views.register),path('logout/', views.logout),]
初步视图编写
from django.shortcuts import renderfrom django.shortcuts import redirect# Create your views here.def index(request):passreturn render(request, 'login/index.html')def login(request):passreturn render(request, 'login/login.html')def register(request):passreturn render(request, 'login/register.html')def logout(request):passreturn redirect("/login/")
创建所需HTML文件
在login app下创建 tempaltes/login/ ,其下放置index.html, login.html, register.html
登录界面
login()
页面访问和处理数据都在同一个函数中
- 第一访问页面
/login/时,loginRegister/urls.py路由转发进入login方法,判断到request.method不是post,于是直接返回页面。 - 写入登录信息,由于
action="/login/",loginRegister/urls.py路由转发到login方法,判断request.method为post,处理数据,跳转到index界面
redirect()
传递的值是需要路由转发的,经过loginRegister/urls.py ,查到 /index/ 所属页面
render()
传递的是app内的网页值,系统会直接找到网页,不需要经过loginRegister/urls.py
def login(request):if request.method == 'POST':username = request.POST.get('username')password = request.POST.get('password')print(username, password)return redirect('/index/') #返回return render(request, 'login/login.html')
数据验证
数据验证分前端页面验证和后台服务器验证。前端验证可以通过专门的插件或者自己写JS代码实现,也可以简单地使用HTML5的新特性。
表单
创建表单模型
widgets见
# login/forms.pyfrom django import formsclass UserForm(forms.Form):username = forms.CharField(label="用户名", max_length=128)password = forms.CharField(label="密码", max_length=256, widget=forms.PasswordInput)
视图
def login(request):if request.method == 'POST':login_form = forms.UserForm(request.POST)message = '请检查填写的内容!'if login_form.is_valid():username = login_form.cleaned_data.get('username')password = login_form.cleaned_data.get('password')
页面
为了页面美观等,需要手动渲染样式,input属性在forms.py字段的widgets属性中设置
<div class="form-group">{{ login_form.username.label_tag }}{{ login_form.username}}</div><div class="form-group">{{ login_form.password.label_tag }}{{ login_form.password }}</div>
图片验证码
django-simple-captcha 提供了验证码功能
安装
注册到app列表
写入app列表,而且captcha要写入数据库
修改forms.py
**from django import forms
from captcha.fields import CaptchaField**
class UserForm(forms.Form):
username = forms.CharField(label="用户名", max_length=128, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': "Username",'autofocus': ''}))
password = forms.CharField(label="密码", max_length=256, widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': "Password"}))
captcha = CaptchaField(label='验证码')
添加路由
path('captcha/', include('captcha.urls')) # 增加这一行
session会话
保存用户的状态、数据,可用于验证用户是否登录
登录
if user.password == password:
request.session['is_login'] = True # 后续用来验证是否已登录
request.session['user_id'] = user.id
request.session['user_name'] = user.name
return redirect('/index/')
else:
message = '密码不正确!'
return render(request, 'login/login.html', locals())
登出
def logout(request):
if request.session.get('is_login', None):
request.session.flush()
return redirect('/login/')
return redirect('/login/')
注册
register()
def register(request):
if request.session.get('is_login', None):
return redirect('/index/')
if request.method == 'POST':
register_form = forms.RegisterForm(request.POST)
message = "请检查填写的内容!"
if register_form.is_valid():
username = register_form.cleaned_data.get('username')
password1 = register_form.cleaned_data.get('password1')
password2 = register_form.cleaned_data.get('password2')
email = register_form.cleaned_data.get('email')
sex = register_form.cleaned_data.get('sex')
if password1 != password2:
message = '两次输入的密码不同!'
return render(request, 'login/register.html', locals())
else:
same_name_user = models.User.objects.filter(name=username)
if same_name_user:
message = '用户名已经存在'
return render(request, 'login/register.html', locals())
same_email_user = models.User.objects.filter(email=email)
if same_email_user:
message = '该邮箱已经被注册了!'
return render(request, 'login/register.html', locals())
new_user = models.User()
new_user.name = username
new_user.password = password1
new_user.email = email
new_user.sex = sex
new_user.save()
return redirect('/login/')
else:
return render(request, 'login/register.html', locals())
register_form = forms.RegisterForm()
return render(request, 'login/register.html', locals())
加密
# import hashlib
def hash_code(s, salt='mysite'):
h = hashlib.sha256()
s += salt
h.update(s.encode())
return h.hexdigest()
Github管理项目
requirements.txt
requirements.txt文件是一个项目的依赖文件。
进入虚拟环境,切换到项目根目录下,使用pip工具的freeze参数。
(venv)
~/PycharmProjects/loginRegister
▶ pip3 freeze > ./requirements.txt
他人如果拷贝了我们的代码,要安装第三方库依赖的话,只需要:
pip install -r requirements.txt
就可以一次性安装好所有的库了。
.gitignore
在项目代码中,有一些文件是不能上传的,比如密码文件、数据库文件、核心配置文件等等,还有一些是不用上传的,比如临时文件。为了让git自动忽略这些文件,我们需要创建一个忽略名单。
在项目根目录下新建一个.gitignore文件
在.gitignore文件里写入下面的内容:
.gitignore
venv
.idea
settings.py
db.sqlite3
mysite/__pycache__/
这些文件将不会上传到Github中,也不会进行版本管理
特殊文件处理
有些文件是项目必需但又会泄露隐私,可以在相同路径下创建类似文件,如 [settings.example.py](http://settings.example.py) ,把敏感信息删除或修改。
说明文件
[README.md](http://readme.md) 在文件里写入项目说明,使用方法,注意事项等等所有你认为需要说明的东西
许可文件
代码授权许可。。。
使用Github仓库源码
- 创建虚拟环境
- 使用pip安装第三方依赖
- 修改settings.example.py文件为settings.py
- 运行migrate命令,创建数据库和数据表
- 运行python manage.py runserver启动服务器
重用app
打包app
打包的本质,就是封装你的源代码和文件成为一种新的数据包装格式,有利于传输、分发和安装。在Django中打包一个app只需要下面八个步骤:
文件准备
在你的Django项目目录外面,为我们的login应用,准备一个父目录,这里取名django-login-register。
额外提醒:
为你的app选择一个合适的名字:在取名前,去PyPi搜索一下是否有重名或冲突的app(包)已经存在。建议给app的名字加上“django-”的前缀。名字不能和任何Django的contrib packages中的app重名,例如auth、admin、messages等等。
拷贝文件
将mysite/login目录中的所有内容拷贝到django-login-register目录内。将login/migrations目录中,除了__init__.py外的文件全部删除,这些被删除的文件是我们先前在本地数据库的操作记录,不应该打包到里面。
创建说明文档
创建一个说明文档django-login-register/README.rst,写入下面的内容:
=====
登录和注册系统
=====
## 这是一个用户登录和注册教学项目
## 这是一个可重用的登录和注册APP
## 该项目教程发布在www.liujiangblog.com
## 简单的使用步骤:
1. 创建虚拟环境
2. 使用pip安装第三方依赖
3. 添加相应的路由
4. 配置settings
5. 运行migrate命令,创建数据库和数据表
6. 链接你的index页面
7. 运行python manage.py runserver启动服务器
## 路由设置:
from django.contrib import admin
from django.urls import path, include
from login import views
urlpatterns = [ path('admin/', admin.site.urls), path('index/', views.index), path('login/', views.login), path('register/', views.register), path('logout/', views.logout), path('confirm/', views.user_confirm), path('captcha/', include('captcha.urls'))
]
## settings配置:
1. 在INSTALLED_APPS中添加‘login’,'captcha'
2. 默认使用Sqlite数据库
3. LANGUAGE_CODE = 'zh-hans'
4. TIME_ZONE = 'Asia/Shanghai'
5. USE_TZ = False
# 邮件服务设置
6. EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
7. EMAIL_HOST = 'smtp.sina.com'
8. EMAIL_PORT = 25
9. EMAIL_HOST_USER = 'xxxx@sina.com'
10. EMAIL_HOST_PASSWORD = 'xxxxx'
# 注册有效期天数
11. CONFIRM_DAYS = 7
这其实是一个纯文本文件,内容和格式完全自由,但核心要点是注明你的app功能和简单的使用方法。
添加授权声明
创建一个django-login-register/LICENSE版权申明文件。大多数Django相关的app都基于BSD版权。如果不是发布到正式场合,可以不写。
创建setup.py脚本
创建一个django-login-register/setup.py文件,包含了编译和安装app的配置细节。这种配置脚本的具体语法,请前往setuptools的官方文档获取详细的教程。下面是一个范例,大多数情况下,你在此基础上改改就可以了:
iption='一个通用的用户注册和登录系统',
long_description=README,
url='https://www.liujiangblog.com/',
author='liujiang',
author_email='yourname@example.com',
classifiers=[
'Environment :: Web Environment',
'Framework :: Django',
'Framework :: Django :: 2.2', # replace "X.Y" as appropriate
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License', # example license
'Operating System :: OS Independent',
'Programming Language :: Python',
# Replace these appropriately if you are stuck on Python 2.
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
],
)
例子中的配置项看起来有点复杂,实际简单得不要不要的。耐心点,就完全不是问题。
需要注意的是,如果你的readme文件中有中文,那么在setup.py文件的open方法中要指定encoding='utf-8',否则会出现编码错误。
创建MANIFEST文件
默认情况下,只有Python的模块和包会被打包进我们的app内。为了包含一些其它的文件,比如静态文件、templates模板等非Python语言编写的文件,需要创建一个django-login-register/MANIFEST.in文件,并写入下面的内容:
include LICENSE
include README.rst
recursive-include login/static *
recursive-include login/templates *
recursive-include docs *
添加doc目录
该步骤可选,但是强烈推荐将详细的说明文档一起打包。创建一个空的目录django-login-register/docs,用于放置app相关的所有文档。同时确认在django-login-register/MANIFEST.in文件内有一行recursive-include docs *。需要注意的是,如果docs目录是空的,那么它不会被打包进去。
执行打包动作
在django-login-register目录内,运行python setup.py sdist命令。这将会创建一个dist目录,并生成django-login-register-1.0.tar.gz文件。同时生成一个django_login_register.egg-info文件夹。
八个步骤完成了,我们的app也就打包好了。
使用打包好的app
实际使用时,我们只需要使用django-login-register-1.0.tar.gz这个文件就可以了。
在安装包的时候,最好是以个人用户的身份安装,而不是全系统范围的身份。这样可以有效减少给别的用户带去的影响或被别的用户影响。当然,最好的方式是在virtualenv环境,这种类似隔离的沙盒环境中使用(此时,不需要--user选项)。
安装
pip install django-login-register-1.0.tar.gz
pip list # 查看安装环境
在虚拟环境中使用pip安装的时候,一定要注意pip和Python的对应关系,所有的重点都是,你必须确保包被安装在了正确的位置。
最后需要提醒的是,这种方式安装后,app的文件会放在Python环境的site-packages中,而不是以源代码的形式放在我们认为的项目中。我们可以import login,可以在settings中注册‘login’,但要修改login中的源码,则需要去site-packages中。
一定要注意,pip安装的时候,使用的名字是django-login-register-1.0.tar.gz,而不是pip install login。实际使用中import的时候是‘import login’,而不是‘import django-login-register’。
安装成功后,再安装依赖包django-simple-captcha等等,然后在新Django项目的INSTALLED_APPS设置中注册login和captcha,按照使用说明,添加路由,修改settings配置,创建数据表,链接新的index页面,然后启动服务器,就可以使用这个app了。
卸载
pip uninstall django-login-register
对于新手,一定要清楚的是:以使用一个第三方库的形式来重用这个app
