Django request.user在重定向后变为匿名

时间:2016-08-27 02:19:38

标签: python django redirect

在我的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')

1 个答案:

答案 0 :(得分:2)

是。请参阅有关session invalidation on password change的文档。要修复它,请特别注意这一点:

  

Django,PasswordChangeViewuser_change_password管理员中django.contrib.auth视图中包含的默认密码更改视图,使用新密码哈希更新会话,以便用户更改自己的密码不会自己登出。如果您有自定义密码更改视图并希望具有类似行为,请使用update_session_auth_hash()功能。