在我的Django应用程序中,我从django.contrib.auth.models创建了一个用户,我在多个视图函数中使用request.user没有问题。在我的一个视图功能中,我更改用户密码,保存用户,并将客户端重定向到另一个视图功能。一旦我尝试从该功能中的请求中获取用户,该用户就是匿名用户。使用User.set_password()或重定向后,是否会让用户退出会话?
views.py
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render
from .models import Profile
from .forms import ProfileForm, PasswordForm
def sign_in(request):
form = AuthenticationForm()
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
if form.user_cache is not None:
user = form.user_cache
if user.is_active:
login(request, user)
return HttpResponseRedirect(
reverse('home') # TODO: go to profile
)
else:
messages.error(
request,
"That user account has been disabled."
)
else:
messages.error(
request,
"Username or password is incorrect."
)
return render(request, 'accounts/sign_in.html', {'form': form})
def sign_up(request):
form = UserCreationForm()
if request.method == 'POST':
form = UserCreationForm(data=request.POST)
if form.is_valid():
form.save()
user = authenticate(
username=form.cleaned_data['username'],
password=form.cleaned_data['password1']
)
new_profile = Profile.objects.create(user=user)
login(request, user)
messages.success(
request,
"You're now a user! You've been signed in, too."
)
return HttpResponseRedirect(reverse('home')) # TODO: go to profile
return render(request, 'accounts/sign_up.html', {'form': form})
def sign_out(request):
logout(request)
messages.success(request, "You've been signed out. Come back soon!")
return HttpResponseRedirect(reverse('home'))
def profile(request):
user = request.user
try:
account = Profile.objects.get(user=user)
except Profile.DoesNotExist:
account = None
print(account.first_name)
context = {'account': account}
return render(request, 'accounts/profile.html', context)
def edit(request):
account = Profile.objects.get(user=request.user)
form = ProfileForm(instance=account)
if request.method == 'POST':
account = Profile.objects.get(user=request.user)
form = ProfileForm(request.POST, request.FILES)
if form.is_valid():
account.first_name = form.cleaned_data['first_name']
account.last_name = form.cleaned_data['last_name']
account.email = form.cleaned_data['email']
account.bio = form.cleaned_data['bio']
account.avatar = form.cleaned_data['avatar']
account.year_of_birth = form.cleaned_data['year_of_birth']
account.save()
context = {'account': account}
return HttpResponseRedirect('/accounts/profile')
else:
x =form.errors
context = {'form': form, 'errors': form.errors}
return render(request, 'accounts/edit.html', context)
else:
context = {'form': form}
return render(request, 'accounts/edit.html', context)
def change_password(request):
user = request.user
if request.method == 'POST':
form = PasswordForm(request.POST)
if form.is_valid():
cleaned_data = form.cleaned_data
if not user.check_password(cleaned_data['old_password']):
form.add_error('old_password', 'Old password is incorrect')
context = {'form': form}
return render(request, 'accounts/password.html', context)
try:
user.set_password(cleaned_data['new_password'])
user.save()
return HttpResponseRedirect('/accounts/profile')
except Exception as e:
form = PasswordForm()
context = {'form': form}
return render(request, 'accounts/password.html', context)
else:
form = PasswordForm()
context = {'form': form}
return render(request, 'accounts/password.html', context)
forms.py
class PasswordForm(forms.Form):
old_password = forms.CharField(max_length=200)
new_password = forms.CharField(max_length=200)
confirm_password = forms.CharField(max_length=200)
def clean(self, *args, **kwargs):
cleaned_data = super(PasswordForm, self).clean()
if 'new_password' in cleaned_data:
new_password = cleaned_data['new_password']
else:
new_password = None
if 'confirm_password' in cleaned_data:
confirm_password = cleaned_data['confirm_password']
else:
confirm_password = None
if confirm_password and new_password:
if new_password != confirm_password:
self.add_error('confirm_password', 'Passwords do not match')
答案 0 :(得分:2)
是。请参阅有关session invalidation on password change的文档。要修复它,请特别注意这一点:
Django,
PasswordChangeView
和user_change_password
管理员中django.contrib.auth
视图中包含的默认密码更改视图,使用新密码哈希更新会话,以便用户更改自己的密码不会自己登出。如果您有自定义密码更改视图并希望具有类似行为,请使用update_session_auth_hash()
功能。