Django 的 Session 框架
session 可以存储和获取访问者的数据信息,这些信息保存在服务器上(默认是数据库中),以 cookies 的方式发送和获取一个包含 session ID 的值,并不是用 cookies 传递数据本身,从而避免了大部分的常见 cookie 问题。
启用 session
编辑 settings.py 中的一些配置
MIDDLEWARE_CLASSES 确保其中包含以下内容
'django.contrib.sessions.middleware.SessionMiddleware',
INSTALLED_APPS 是包含
'django.contrib.sessions',
这些是默认启用的。如果不用的话,也可以关掉这个以节省一点服务器的开销。
在视图中使用 session
request.session 可以在视图中任何地方使用,它类似于 python 中的字典
# 创建或修改 session:
request.session[key] = value
# 获取 session:
request.session.get(key,default=None)
# 删除 session
delrequest.session[key] # 不存在时报错`
一个简化的登陆认证:
# 用户登录
@csrf_exempt
def user_login(request):
if request.method == 'POST':
# If we didn't post, send the test cookie along with the login form.
request.session.set_test_cookie()
# Check that the test cookie worked (we set it below):
if request.session.test_cookie_worked():
# The test cookie worked, so delete it.
request.session.delete_test_cookie()
# logic to check username/password
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password) #用户验证
if user:
login(request, user) #用户登录
request.session['user_id'] = user.id
return HttpResponse("You're logged in.")
else:
return HttpResponse("Invalid login details given")
# The test cookie failed, so display an error message. If this
# were a real site, we'd want to display a friendlier message.
else:
return HttpResponse("Please enable cookies and try again.")
# 用户登出
@csrf_exempt
@login_required
def user_logout(request):
try:
del request.session['user_id']
except KeyError:
pass
return HttpResponse("You're logged out.")
当登陆时验证用户名和密码,并保存用户 id 在 session 中,这样就可以在视图中用 request.session[‘member_id’] 来检查用户是否登陆,当退出的时候,删除掉它。
重写 authenticate 实现邮箱和用户名登录
1、在 setting.py 中进行配置:
AUTHENTICATION_BACKENDS = (
'questionnaire.custom.EmailOrUsernameModelBackend',
)
使用的认证后台通过 AUTHENTICATION_BACKENDS 设置指定。它应该是一个包含 Python 路径名称的元组,它们指向的 Python 类知道如何进行验证。这些类可以位于 Python 路径上任何地方。
2、在 custom.py 中重新定制 authenticate() 方法
class EmailOrUsernameModelBackend(ModelBackend):
"""
This is a ModelBacked that allows authentication with either a username or an email address.
"""
def authenticate(self, request, username=None, password=None, **kwargs):
# n.b. Django <2.1 does not pass the `request`
user_model = get_user_model()
if username is None:
username = kwargs.get(user_model.USERNAME_FIELD)
# The `username` field is allows to contain `@` characters so
# technically a given email address could be present in either field,
# possibly even for different users, so we'll query for all matching
# records and test each one.
users = user_model._default_manager.filter(
Q(**{user_model.USERNAME_FIELD: username}) | Q(email__iexact=username)
)
# Test whether any matched user has the provided password:
for user in users:
if user.check_password(password):
return user
if not users:
# Run the default password hasher once to reduce the timing
# difference between an existing and a non-existing user (see
# https://code.djangoproject.com/ticket/20760)
user_model().set_password(password)
-
在 django 中对数据库中的内容进行查询时,有时需要包含多个查询条件,此时采用 Q() 方法就很方便了。Q对象 (django.db.models.Q) 可以对关键字参数进行封装,从而更好地应用多个查询。可以组合使用 &(and), (or),~(not)操作符,当一个操作符是用于两个 Q 的对象,它产生一个新的Q对象。 - 因为在 django 中用户的密码存储在数据库中是经过加密的,如果直接用 password==password 来进行验证是不对的。通过 user.check_password(password) 方法来进行验证密码是否正确。