Django request.user becomes anonymous after redirect
<p>In my Django app I create a User from django.contrib.auth.models, and I am using request.user in multiple view functions without a problem. In one of my view functions I change the user password, save the user, and redirect the client to another view function. Once I try to get the user from the request in that function, the user is Anonymous. After using User.set_password() or redirecting, does it take the user out of the session ?</p>

<p>views.py</p>

<pre><code>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)
</code></pre>

<p>forms.py</p>

<pre><code>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')
</code></pre>

<p>Yes. See the documentation about <a href="https://docs.djangoproject.com/en/dev/topics/auth/default/#session-invalidation-on-password-change" rel="nofollow">session invalidation on password change</a>. To fix it, see this bit in particular:</p>

<blockquote>
  <p>The default password change views included with Django, <code>PasswordChangeView</code> and the <code>user_change_password</code> view in the <code>django.contrib.auth</code> admin, update the session with the new password hash so that a user changing their own password won't log themselves out. If you have a custom password change view and wish to have similar behavior, use the <code>update_session_auth_hash()</code> function.</p>
</blockquote>

python django redirect user