Not understanding Django admin login - django

I'm trying to use the admin login mechanisms in Django, and redirect to the requested page, and I'm getting a 404 as it's trying to redirect to the url posted, not to the url represented by the next parameter. I'm obviously not understanding something, because when I step through the contrib.auth.login view, it's not parsing the next parameter at all. For example, I have the following view (the main page of the site)
#login_required(login_url='/sdc/admin/login')
def cb_index(request):
#snip
return render_to_response('chargeback_base.html', variables)
So when I enter the url for the cb_index view, /sdc/chargeback/, it properly redirects to the login page, with the next variable set to /sdc/chargeback/, as shown below.
http://localhost:8000/sdc/admin/login/?next=/sdc/chargeback/
The default login view though, from contrib.auth.views, uses that complete url as the redirect_to not the next parameter, so I always get a 404 instead of being redirected to the next url. I can fix it by adding
redirect_to = request.GET.get('next','')
to the POST section of the view, but I thought this was supposed to be built in functionality and it's not working. And more to the point, since this is an edit to the base view, I have to remember to fix this every time I update, which I don't want to do. What am I not understanding?
EDIT:
Login url follows the admin site urls
url(r'^sdc/admin/', include(admin.site.urls)),
The login template is the included login template from the admin site, no changes.

The django auth app has a login view, which you should explicitly include in your url patterns directly.
(r'^accounts/login/$', 'django.contrib.auth.views.login', name='login'),
See the docs on auth views for more information. You don't need to choose /accounts/login/ as your login url. I just want to make it clear that this view is separate from the admin app.
Update LOGIN_URL='/accounts/login/' in your settings, then you don't have to use the login_url parameter when you use the login_required decorator.
Currently, /sdc/admin/login/ is handled by the admin app, but the admin app does provide a login view for this purpose. If you step through the code, you can see that the AdminSite.login method handles the request. This method sets REDIRECT_FIELD_NAME (in your case 'next')to the request path, then calls the auth login view.

Related

Django-allauth how to redirect to pervious page after login

I'm using Django-allauth , I can successfully redirect it to home page by adding this in settings.py:
LOGIN_REDIRECT_URL = '/home'
But is there anyway I can redirect it to pervious page?
What you're looking for should actually work out of the box by using the redirect field, which is next by default:
https://docs.djangoproject.com/en/3.1/topics/auth/default/#django.contrib.auth.mixins.AccessMixin.get_redirect_field_name
The view that is checking for the access permission and redirecting to the login form only needs to pass the URL the user was previously on. If that field is present, the user will be redirected to that particular page after logging in.
How are you restricting login? I assume you're not passing next? The #login_required decorator and the LoginRequiredMixin for class-based views both set next by default.
This is what the docs say about how LoginView handles POST requests:
If called via POST with user submitted credentials, it tries to log the user in. If login is successful, the view redirects to the URL specified in next. If next isn’t provided, it redirects to settings.LOGIN_REDIRECT_URL (which defaults to /accounts/profile/).

Django - One URL links to two views?

For my home page, I want to be able to have the generic login form, so I linked the homepage URL to the generic login view, like so:
from django.contrib.auth.views import login
urlpatterns = patterns('',
url(r'^$', login),
Now, I also want to have the registration form and view in the homepage as well. This view is called the main_page view. What is the best way for me to be able to use both those views (and the variables which the two views render) in my homepage URL?
You should write your own view to do this. You can't use the default login view but you can use other pieces Django provides:
https://docs.djangoproject.com/en/dev/topics/auth/default/#how-to-log-a-user-in
This is how you login a user.
https://docs.djangoproject.com/en/dev/topics/auth/default/#module-django.contrib.auth.forms
This is a login form if you don't wanna write your own.
If you link 2 url's to single view then Django will only load the view which it encountered first. So no point linking 2 url's to single view.
Few advice's for you:
On login page why not give a link to registration page, if user is not registered then he/she can register.
Or Differentiate your URL with a query string parameter. In case of registration page pass a query string param. Then in the login view check for the query string param, if exists redirect it to registration view else show login page. your homepage url with query string will look like
http://www.example.com?page=r #you can choose any key value pair for query string

Overriding a Django app url to make it Non-accessible

I'm using userena for handling the users' profiles. I created an app that override some of userena views and urls.
In particular I've created two different signup forms, so now I have two separate urls:
url(r'^signup/customer/$',....
url(r'^signup/owner/$',...
The original userena signup form was accessible at r'^signup/$'.
Question: How do I override the userena original signup url in order to make it unavailable?
The original url should not be accessible to anyone, so I guess Django should show a 404 page.
In your root urls.py conf, just override the url which you want to disable and direct it to Django 404 (page not found) view:
from django.views.defaults import page_not_found
url(r'^signup/$',
page_not_found,
name='userena_signup'),
If you are already overriding some views and URLs, you could override the signup URL with a view that just returns a 404 response.

Redirecting to another page after django admin login

I am making a custom administration page in Django. I do not want to reinvent the wheel and thus want to use Django admin login form for the staff to log in and redirect them to /my-url/ afterwards.
However, I can't find the way to redirect user to a custom url after successful login at /admin/.
since I stumbled across the same problem, I noticed the url of the the default login page:
/admin/login/?next=/admin/
so I changed the login page link to
/admin/login/?next=/
to point to the main page
works for the logout page too, nice and simple
I had the same issue.
Instead of redirect after login I used the #staff_member_required decorator
for my view /my-url/ which redirects to the admin login
from django.contrib.admin.views.decorators import staff_member_required
#staff_member_required
def test_list(request):
return HttpResponse('TEST')
If class based views is used check out the method_decorator
The Django auth app comes with a login view which you can hook up to /accounts/login/ or any other url you choose. You can probably use the admin's login template admin/login.html if you don't want to write your own.
By using the login view, the LOGIN_REDIRECT_URL parameter will work. The purpose of the /admin/ page is to display the admin index. I would avoid trying to use it as the login page.
Set LOGIN_REDIRECT_URL in your settings.py file. Documented here.
If you have ?next= parameter set is not enough to set LOGIN_REDIRECT_URL in you setting.py. You need to also handel this parameter. As say docs (https://docs.djangoproject.com/en/4.1/ref/settings/#login-redirect-url):
LOGIN_REDIRECT_URL
Default: '/accounts/profile/'
The URL or named URL pattern where requests are redirected after login
when the LoginView doesn’t get a next GET parameter.
In my case I just set REDIRECT_FIELD_NAME = "" instead of REDIRECT_FIELD_NAME = "next" in my django.contrib.auth and it works fine.

Django built-in login view and errors

I'm using the django.contrib.auth.views.login and .logout views. Very handy, worked out of the box, would deploy again AAA+ etc.
The problem arises since I'm not using a separate login page, but rather I have a login box in every page (unless the user is logged in, of course). And so, when the username/password combination is wrong, I get an error.
Which of these three paths should I choose?
There is a secret way to redirect to next not only on success but also on error. If so, please tell me!
I write my own login view, putting to use Django's message system in the meanwhile
I write a login page (well, it's just missing a template) so I can exploit the full awesomeness of the Django auth system.
One of possible solutions (first + third choices in your list):
You have to provide special login page (that is define registration/login.html)
and for non loged in user each normal page has login form;
if user logins normally (this logic handled in django.contrib.auth.views.login):
for normal page: redirect user to the page from where she loged in;
for login page: if there is next param, redirect there, else redirect to main page;
if user fails to login: redirect (or redraw) login page with errors provided;
if user is loged in: normal page provides a link to logout (special page is still there in case if user want's to re-login or login through another account).
In normal pages, login form should have something like this <input type="hidden" name="next" value="{{ request.path }}" />.
In project settings:
# in settings.py
LOGIN_URL = '/login' # this should coinside with url pattern of login view
LOGOUT_URL = '/logout' # same but for logout view
LOGIN_REDIRECT_URL = '/' # url to main page
N.B.: I don't use django's buildin logout view instead I use my own: almost the same but does logout only for POST requests. This disallows users to logout by <img src='my_site/logout' /> malicious code.