使用allauth插件管理用户登录与注册

转自: http://www.eosones.com/article/04/
django-allauth是最受欢迎的管理用户登录与注册的第三方Django安装包,可以大大简化我们用户注册,登录及账户管理,其核心功能包括用户注册、忘记密码、登录(微信,微博等第三方登录;邮箱验证)、登录后密码重置、邮箱发送密码重置链接、退出等。

安装与设置

运行CMD,打开虚拟环境

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;">pip install django-allauth
</pre>

安装好后设置Myblog / settings.py,将allauth相关APP加入到INSTALLED_APP里去。对于第三方的providers,根据需要添加。 官网Providers文档

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;">INSTALLED_APPS = [
...,
#django-allauth必须安装的app
'django.contrib.sites',
'allauth',
'allauth.account',
'allauth.socialaccount',
#第三方账号相关,根据需求添加
'allauth.socialaccount.providers.weibo',
'allauth.socialaccount.providers.github',
]
</pre>

同时还需要一些设置

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;"> # django-allauth相关设置
AUTHENTICATION_BACKENDS = (
# django admin所使用的用户登录与django-allauth无关
'django.contrib.auth.backends.ModelBackend',
# allauth 身份验证
'allauth.account.auth_backends.AuthenticationBackend',
)

app django.contrib.sites需要的设置

SITE_ID = 1

指定要使用的登录方法(用户名、电子邮件地址两者之一)

ACCOUNT_AUTHENTICATION_METHOD = 'username_email'

要求用户注册时必须填写email

ACCOUNT_EMAIL_REQUIRED = True
</pre>

配置邮箱:allauth 在注册用户时,会给用户填写的邮箱发送一封激活邮件,在重置密码时也可通过邮箱进行重置。如果你没有邮件服务器,可以设置成自己的QQ或163邮箱,localhost环境下一样可以使用。 如何获取邮箱授权码

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;"># smtp 服务器地址
EMAIL_HOST = "smtp.qq.com"

默认端口25,若请求超时可尝试465

EMAIL_PORT = 25

用户名

EMAIL_HOST_USER = "374542101@qq.com"

邮箱代理授权码(不是邮箱密码)

EMAIL_HOST_PASSWORD = "password"

是否使用了SSL 或者TLS(两者选其一)

EMAIL_USE_TLS = True

EMAIL_USE_SSL = True

发送人

EMAIL_FROM = "374542101@qq.com" #

默认显示的发送人,(邮箱地址必须与发送人一致),不设置的话django默认使用的webmaster@localhost

DEFAULT_FROM_EMAIL = "EOSONES 博客 374542101@qq.com"
</pre>

修改时区

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;">LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
</pre>

将 allauth 添加加到总项目的 urls.py 中

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;"># Myblog/urls.py
from django.conf.urls import re_path,include

urlpatterns = [
...,
#django-allauth插件
re_path(r'^accounts/', include('allauth.urls')),
]
</pre>

django-allauth 常见设置选项

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;"># 要求用户注册时必须填写email
ACCOUNT_EMAIL_REQUIRED = True

注册中邮件验证方法: "强制(mandatory)"、 "可选(optional)" 或 "否(none)" 之一

(注册成功后,会发送一封验证邮件,用户必须验证邮箱后,才能登陆)
ACCOUNT_EMAIL_VERIFICATION (="optional")

作用于第三方账号的注册

SOCIALACCOUNT_EMAIL_VERIFICATION = 'optional' / 'mandatory' / 'none'

邮件发送后的冷却时间(以秒为单位)

ACCOUNT_EMAIL_CONFIRMATION_COOLDOWN (=180)

邮箱确认邮件的截止日期(天数)

ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS (=3)

指定要使用的登录方法(用户名、电子邮件地址或两者之一)

ACCOUNT_AUTHENTICATION_METHOD (="username" | "email" | "username_email")

登录尝试失败的次数

ACCOUNT_LOGIN_ATTEMPTS_LIMIT (=5)

从上次失败的登录尝试,用户被禁止尝试登录的持续时间

ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT (=300)

更改为True,用户一旦确认他们的电子邮件地址,就会自动登录

ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION (=False)

更改或设置密码后是否自动退出

ACCOUNT_LOGOUT_ON_PASSWORD_CHANGE (=False)

更改为True,用户将在重置密码后自动登录

ACCOUNT_LOGIN_ON_PASSWORD_RESET (=False)

控制会话的生命周期,可选项还有: "False" 和 "True"

ACCOUNT_SESSION_REMEMBER (=None)

用户注册时是否需要输入邮箱两遍

ACCOUNT_SIGNUP_EMAIL_ENTER_TWICE (=False)

用户注册时是否需要用户输入两遍密码

ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE (=True)

用户不能使用的用户名列表

ACCOUNT_USERNAME_BLACKLIST (=[])

加强电子邮件地址的唯一性

ACCOUNT_UNIQUE_EMAIL (=True)

用户名允许的最小长度的整数

ACCOUNT_USERNAME_MIN_LENGTH (=1)

使用从社交账号提供者检索的字段(如用户名、邮件)来绕过注册表单

SOCIALACCOUNT_AUTO_SIGNUP (=True)

设置登录后跳转链接

LOGIN_REDIRECT_URL (="/")

设置退出登录后跳转链接

ACCOUNT_LOGOUT_REDIRECT_URL (="/")

用户登出是否需要确认确认(True表示直接退出,不用确认;False表示需要确认)

ACCOUNT_LOGOUT_ON_GET (=True)
</pre>

测试效果

首先生成数据库

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;">python manage.py makemigrations
python manage.py migrate
</pre>

登录 admin,将 example.com 改为我们博客的域名,在开发环境下,我们用127.0.0.1:8000,并设置好 site 名字(邮箱中显示)再退出登录。现在你就可以访问以下链接查看allauth的效果了。由于我们已经设置好了邮箱,所以涉及邮箱验证和密码重置部分都可以正常进行的。注册:http://127.0.0.1:8000/accounts/signup/登录:http://127.0.0.1:8000/accounts/login/

django-allauth表单会自带验证,检查用户名和email是否已经注册,同时检查密码强度是否够以及用户输入的两次密码是不是一致。当注册成功后,用户会收到一封邮件来验证邮箱,如果ACCOUNT_EMAIL_VERIFICATION = 'mandatory' ,用户必须通过邮箱验证后才能登陆。如果你不需要邮箱验证,只需要设置 ACCOUNT_EMAIL_VERIFICATION = 'none' 就可以了。

1、内置的Urls

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;">/accounts/login/ #(URL名account_login): 登录
/accounts/signup/ #(URL名account_signup): 注册
/accounts/password/reset/ #(URL名: account_reset_password) :重置密码
/accounts/logout/ #(URL名account_logout): 退出登录
/accounts/password/set/ # (URL名:account_set_password): 设置密码
/accounts/password/change/ #(URL名: account_change_password): 改变密码(需登录)
/accounts/email/ #(URL名: account_email) 用户可以添加和移除email,并验证
/accounts/social/connections/ #(URL名:socialaccount_connections): 管理第三方账户
</pre>

扩展用户模型

django-allauth 并没有提供展示和修改用户资料的功能,也没有对用户资料进行扩展,所以我们需要自定义用户模型来进行扩展。

1、创建 app 及配置

由于 django-allauth 已经占用了 account 这个 app,所以我们可以创建一个叫 Myaccount 的 app,并将其加入 settings.py 配置文件的 INSTALL_APPS 中,同时把 url 也加入到项目 settings.py 中。

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;">python manage.py startapp Myaccount
</pre>

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;"># Myblog/settings.py
INSTALLED_APPS = [
...,
'Myaccount',
#django-allauth必须安装的app
...,
]
</pre>

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;"># Myblog/urls.py
from django.conf.urls import re_path,include

urlpatterns = [
...,
#django-allauth插件
re_path(r'^accounts/', include('allauth.urls')),
#django-allauth用户自定义信息扩展
re_path(r'^accounts/', include('Myaccount.urls',namespace='accounts')),
]
</pre>

因为我们希望用户在登录或注册成功后,自动跳转到个人信息页 "/accounts/profile/",所以在前面的配置中加入了如下代码

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;"># Myblog/settings.py

LOGIN_REDIRECT_URL = "/accounts/profile/"
</pre>

2、创建用户模型及表单

首先自定义的 User 模型继承了 AbstractUser ,AbstractUser 是 django 自带用户类,可扩展用户个人信息,AbstractUser 模块下有:password、username、first_name、last_name、email、last_loginl、is_superuserl、is_staffl、is_activel、date_joined 字段,自定义用户User扩展了 nickname、link 及头像 avatar 字段,此处重写了User的 save() 方法以便上传的头像以用户名为文件夹分类。

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;"># Myaccount/models.py

from django.db import models

from django.contrib.auth.models import User

from django.contrib.auth.models import AbstractUser

用pillow、django-imagekit模块设置图片,可以处理图片,生成指定大小的缩略图,前端显示src="{{ user.avatar.url }}

from imagekit.models import ProcessedImageField
from imagekit.processors import ResizeToFill

扩展Django自带的User模型字

class User(AbstractUser):
nickname = models.CharField(max_length=30, blank=True, null=True, verbose_name='昵称')
# 扩展用户个人网站字段
link = models.URLField('个人网址', blank=True, help_text='提示:网址必须填写以http开头的完整形式')
# 扩展用户头像字段,upload_to后必须是相对路径,上传路径已设置为media,因此upto不需要media/avatar,数据库中avatar/...,前端用avatar.url为media/avatar/...
avatar = ProcessedImageField(upload_to='avatar',default='avatar/default.png',verbose_name='头像',
processors=[ResizeToFill(100, 100)], # 处理后的图像大小
format='JPEG', # 处理后的图片格式
options={'quality': 95} # 处理后的图片质量
)

#重写User的save()方法保存上传的头像目录
def save(self, *args, **kwargs):
# 当用户更改头像的时候,avatar.name = '文件名',其他情况下avatar.name = 'upload_to/文件名'
if len(self.avatar.name.split('/')) == 1:
  self.avatar.name = self.username + '/' + self.avatar.name
#调用父类的save()方法后,avatar.name就变成了'upload_to/用户名/文件名'
super(User, self).save()

# 定义网站管理后台表名
class Meta:
  verbose_name = '用户信息' 
  verbose_name_plural = verbose_name #指定模型的复数形式是什么,如果不指定Django会自动在模型名称后加一个’s’
  ordering = ['-id']
  #admin后台显示名字关联到此表的字段的后天显示名字
def __str__(self):
  return self.username

</pre>

为了让 Django 能够识别自定义的用户模型,需要在 settings.py 中需配置AUTH_USER_MODEL='Myaccount.User',注册的用户就会基于自定义User模型创建,并一同创建account中与自定义User关联的模型。

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;"># Myaccount/forms.py
from django import forms
from .models import User

class ProfileForm(forms.Form):
class Meta:

关联的数据库模型,这里是用户模型

model = User

前端显示、可以修改的字段(admin中)

fields = ['nickname''link', 'avatar']
</pre>

3、创建视图并配置URLs

我们需要创建2个URLs和对应的视图来实现用户资料展示和用户资料编辑页面。

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;"># Myaccount/urls.py
from django.conf.urls import re_path
from . import views

app_name = "Myaccount"

urlpatterns = [
re_path(r'^profile//pre>, views.profile, name='profile'),
re_path(r'^profile/update//pre>, views.profile_update, name='profile_update'),
]
</pre>

因为我们希望用户在登录或注册后自动跳转到/accounts/profile/, 需要在 settings.py 中需配置

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;">LOGIN_REDIRECT_URL = '/accounts/profile/'
</pre>

视图函数根据需求自定义,本博客前端用的是Ajax请求修改网站link与头像avatar供参考

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;">#Myaccount/views.py

from django.shortcuts import render
from django.http import HttpResponse

from Myaccount import models

Create your views here.

auth中用户权限有关的类。auth可以设置每个用户的权限。

from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt

使用login_required装饰器,用户只有登录了才能访问其用户资料

@login_required

个人信息

def profile(request):
# AUTH_USER_MODEL 类型的对象,表示当前登录的用户。
user = request.user
return render(request, 'account/profile.html', {'user': user})

import json
import base64
@login_required # 使用login_required装饰器,用户只有登录了才能访问其用户资料
@csrf_exempt #取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
def profile_update(request):
#request.is_ajax(): #判断请求头中是否含有X-Requested-With的值
if request.is_ajax():
key=request.POST.get('key')#request.POST.get('')不存在默认为空,request.POST[]不存在报错
if key=='link':
link=request.POST['link']
username=request.POST['username']
models.User.objects.filter(username=username).update(link=link)
link=models.User.objects.filter(username=username).first().link
linkJson={'link':link}
return HttpResponse(json.dumps(linkJson))
elif key=='avatar':
username=request.POST['username']
#用ModelForm可代替手动编写代码存储上传文件
user_profile=models.User.objects.filter(username=username).first()
user_profile.avatar=request.FILES.get('avatar')
user_profile.save()
url=user_profile.avatar.url
dataJson={'url':url}
return HttpResponse(json.dumps(dataJson))
</pre>

4、设计前端模板

前端根据需求自定义设计,本博中客个人信息只允许更改头像与个人网站,参考请到Github查看源码。

image

需要注意前后端的交互信息,通过View中传来的当前用户模型User,可通过Django的模板语言显示用户名:{{ user.username }},用户邮箱:{{ user.link }}、用户头像链接:{{ user.avatar.url }}、以及用户邮箱:{{ user.emailaddress_set .0}}(django-allauth在注册用户时创建的ACCOUNTS表,关联自定义模型User,包含用户的邮箱信息及各种方法)、Django-allauth判断邮箱是否验证:{% if user.emailaddress_set .0.verified %}、Django判断用户是否登录:{% if user.is_authenticated %}等等。

美化页面模板

django-allauth自带的页面很简陋,我们需要进行美化。如果你是通过pip安装的django-allauth,模板位置一般在python安装位置或者虚拟环境下的blog_env\Lib\site-packages中,找到\allauth\templates下的整个account文件夹,或者从github上( allauth项目地址 )将allauth的/templates/accounts/文件夹整个拷贝到你的本地项目中的templates目录下,因为django-allauth总是会在templates/accounts/文件夹中寻找模板。

1、美化base.html

不管是注册,登录还是重置密码页面,html模板主要内容都是表单。我们将使用bootstrap迅速美化模板和表单。最快速的方式就是修改base.html(如果没有该文件,你需要创建一个),加入boostrap样式和js。

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;"><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block head_title %} {% endblock %}</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" >
</head>
<body>

<main>
<div class="container">
{% block content %}
{% endblock %}
</div>
</main>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>

</body>
</html>
</pre>

我们以注册页面为例,教你如何美化 django-allauth 的表单。注册页面默认的 signup.html 代码如下,我们先不做任何修改。

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;">{% extends "account/base.html" %}

{% load i18n %}

{% block head_title %}{% trans "Signup" %}{% endblock %}

{% block content %}
<h1>{% trans "Sign Up" %}</h1>

<p>{% blocktrans %}Already have an account? Then please <a href="{{ login_url }}">sign in</a>.{% endblocktrans %}</p>

<form class="signup" id="signup_form" method="post" action="{% url 'account_signup' %}">
{% csrf_token %}
{{ form.as_p }}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<button type="submit">{% trans "Sign Up" %} »</button>
</form>

{% endblock %}
</pre>

2、美化注册表单

一个标准的 Boostrap 表单代码如下,每个输入字段 field 都是包围在div里的class="form-group",同时每个 input 的 css 都有 form-control 这个属性。而我们django的表单渲染 form.as_p 或则 form.as_table 显然满足不了我们的要求,因为我们没法将 css 类名加进去。

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;"><form>
<div class="form-group">
<label for="id_email">Email address</label>
<input type="email" class="form-control" id="id_email" name="email">
</div>
<div class="form-group">
<label for="id_password">Password</label>
<input type="password" class="form-control" id="id_password" name="password">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</pre>

当然可以使用自定义widge的属性来给各个字段添加css,或者直接使用django-crispy-forms表单,这两种相对耦合度较高,此处推荐使用插件django-widget-teaks,在前端模板中不仅可以为字段添加样式,还提供了强大的render_field方法,可以自定义某个字段的css和提示词placeholder。 进入CMD,打开虚拟环境

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;">pip install django-widget-tweaks
</pre>

安装成功后,需要把它加到 INSTALLED_APP 中,这时在模板中{% load widget_tweaks %},你就可以给你想要的字段添加css了。以signup.html,我们给每个输入字段都加入了form-control属性。

<pre style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 0.93em; display: block; padding: 1em; margin: 0px 0px 1.5em; line-height: 1.45; color: rgb(51, 51, 51); word-break: break-all; overflow-wrap: break-word; background: url("/static/images/blueprint.png") 0% 0% / 30px, 0% 0% / 30px 30px rgb(246, 246, 246); border: none; border-radius: 4px; max-height: 35em; position: relative;">{% extends "account/base.html" %}

{% load i18n %}
{% load widget_tweaks %}

{% block head_title %}{% trans "Signup" %}{% endblock %}

{% block content %}
<h1>{% trans "Sign Up" %}</h1>

<p>{% blocktrans %}Already have an account? Then please <a href="{{ login_url }}">sign in</a>.{% endblocktrans %}</p>

<form class="signup" id="signup_form" method="post" action="{% url 'account_signup' %}">
{% csrf_token %}

 {% for hidden in form.hidden_fields %}
  {{ hidden }}
{% endfor %}

{% for field in form.visible_fields %}
  <div class="form-group">
    <label for="{{ field.id_for_label }}">{{ field.label }}</label>
    {{ field|add_class:'form-control' }}
    {% for error in field.errors %}
      <span class="help-block">{{ error }}</span>
    {% endfor %}
  </div>
{% endfor %}

{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}

<div class="form-group">

<button type="submit" class="btn btn-success"">{% trans "Sign Up" %}</button>
</div>
</form>

{% endblock %}
</pre>

根据页面自定义功能,美化表单后,添加到页面中。本博客设计如下图所示,参考前端代码请到 Github 查看。(第三方登录方式添加到INSTALLED_APP中后,便会出现在Login模板中,第三方列表模板位置在插件包中的allauth\templates\socialaccount\snippets\provider_list.html 中,可进行自定义美化)。安照此方法,可依次将需要的模板进行美化。

image

3、修改邮件信息

注册修改密码的过程中,都会收到邮件信息,在我们复制到templates\account\mail文件中的txt文件即是我们邮件中的提示信息,根据需求自定义修改

第三方账号登录

1、Github

1、首先在Github中申请 OAuth Github OAuth注册页面,要注意将回调地址callback URL设置为 http://127.0.0.1:8000/accounts/github/login/callback/,设置完成后可在账号的 Settings / Developer settings / OAuth Apps 中查找更新,上线需要将127.0.0.1:8000更新为我们的博客域名

image

2、进入admin后台,更新站点,将example.com改为我们博客的域名,在开发环境下,我们用127.0.0.1:8000,然后点击 SOCIAL ACCOUNTS 下的 Social application,增加一个application,如下图所示

image

Provider选Github,这里的Provider就是我们在INSTALLED_APP里增加的第三方socialaccount.provider,client id 和 secret key 我们在github注册应用里获得了,将 sites 加入到右边 选中的 sites。 完成以上设置后,注销,然后回到登录页面,选中 Github 登录,授权应用即可,成功登录后,邮箱里也会收到一份激活邮件,这是因为 django-allauth 会自动为我们添加一个本地账号,根据你的 social account 用户名和 email 。

2、微信

1、 首先注册微信开放平台账号,登录后在管理中心—网站应用—创建网站应用,填写网站相关信息进行申请,一般会在7个工作日内完成审核。

image

需注意的是,注册信息需要公章,目前没有发现个人注册的方法,卒。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容