[Solved]-Django after @login_required redirect to next

15πŸ‘

βœ…

The query string is implicitly passed to any view, without you having to write any special code.

All you have to do is make sure that the next key is passed from the actual login form (in your case, this is the form that is rendered in /accounts/login/), to the /accounts/auth view.

To do that, you need to make sure you have the request template context processor (django.core.context_processors.request) enabled in your settings. To do this, first you need to import the default value for TEMPLATE_CONTEXT_PROCESSORS, then add the request processor to it in your settings.py, like this:

from django.conf import global_settings

TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
    "django.core.context_processors.request",
) 

Then in the form:

<form method="POST" action="/accounts/auth">
    {% csrf_token %}
    <input type="hidden" name="next" value="{{ request.GET.next }}" />
    {{ login_form }}
    <input type="submit">
</form>

Now, in your /accounts/auth view:

def foo(request):
    if request.method == 'POST':
        # .. authenticate your user


        # redirect to the value of next if it is entered, otherwise
        # to /accounts/profile/
        return redirect(request.POST.get('next','/accounts/profile/'))
πŸ‘€Burhan Khalid

3πŸ‘

What you are looking for is a login decorator.

In your views.py

from django.contrib.auth.decorators import login_required

@login_required(login_url="/accounts/login/")
def profile( request ):
   """your view code here"""
   return HttpResponse("boo ya", "text/html")

Then in your urls.py add the authentication url

(r'^accounts/login/$', 'django.contrib.auth.views.login'),

Finally: Make sure you have django.contrib.auth in your installed apps, and AuthenticationMiddleware installed.

settings.py

INSTALLED_APPS = (
   -- snip --,
   'django.contrib.auth',
   )


MIDDLEWARE_CLASSES = (
   -- snip --,
   'django.contrib.auth.middleware.AuthenticationMiddleware',
   )

your templates/registration/login.html

<form method="POST" action="/accounts/login/">
   {% csrf_token %}
   <input type="hidden" name="next" value="{{ next }}" />
   {{ login_form }}
   <input type="submit">
</form>

1πŸ‘

What I have ended up doing is the following. To me this seems like a bit of a hack job. Is there any better way to use login with a csrf?

views:

def login(request):
  c={}
  c.update(csrf(request))
  if 'next' in request.GET:
    c['next'] = request.GET.get('next')
  return render_to_response('login.html', c)

def auth_view(request):
  username = request.POST.get('username', '')
  password = request.POST.get('password', '')
  user = auth.authenticate(username=username, password=password)

  if user is not None:
    auth.login(request, user)

    if request.POST.get('next') != '':
      return HttpResponseRedirect(request.POST.get('next'))
    else:
      return HttpResponseRedirect('/accounts/loggedin')
  else:
    return HttpResponseRedirect('/accounts/invalid')

login.html:

<input type="hidden" name="next" value="{{ next }}"/>
πŸ‘€Matt Stokes

1πŸ‘

Faced similar situation sometime back. To solve this I wrote my own decorator –

def validate_request_for_login(f):
    def wrap(request):
        if not request.user.is_authenticated():
            return redirect("/login?next=" + request.path)
        return f(request)
    return wrap

Above decorator checks for user authentication. If user is not authenticated then redirect the user to login page by passing the url from request object.

πŸ‘€anuragal

0πŸ‘

def login_user(request):
    if request.method=='POST':
        print(request.POST,request.GET.get('next'))
        username=request.POST['email']
        password=request.POST['password']
        user = authenticate(request,username=username,password=password)
        if user:
            login(request,user)
        else:
            print('user not found')
            messages.error(request,'Invalid Credentials')
            return render(request, "login.html")
        return redirect(request.GET.get('next','/'))
    return render(request, "login.html")

0πŸ‘

I found options here for solving this question …
I know you found your answer but here for another one…

urls.py

path('', Home.as_view(), name='home')

after login you need to use redirect like this (don’t use render with template name then it gives you problem), then you go to the perfect home URL…

view.py

return redirect('home')
πŸ‘€BiswajitPaloi

Leave a comment