I am getting started with Django and I found something I don’t understand very well when it comes to user authentication (using the typical django.contrib.auth mechanism).
When I create a “site” using
django-admin.py startproject mysite
I understand I create something like a “server”. Then, I need to create an app (as explained in the “getting started” tutorial). I create my models for the app, not for the server. The idea I have (which may be totally wrong) is that apps are something fairly independent among themselves (pretty isolated from each other). I create my models for each app, there is a different set of “views” per app, etc.
But when it comes to user management, that managing seems to be global for the whole project (or “server”): All the settings are specified through the global settings.py file, the built-in login pages are stored in the global templates/ directory… What if I have two apps and I want the login pages for them to have a different aspect? What if after a successful login, I want to redirect to an specific page of app#1 or to another specific page of app#2 depending on the app the user was trying to log in? Maybe I am missunderstanding the whole concept behind a Django app?
Basically, I have a mystartapp application inside a project called myserver. I am using the built-in login view, sending a form to "django.contrib.auth.views.login". With the default configuration, a successful login was trying to redirect me to http://127.0.0.1:8000/accounts/profile/, which I don’t have.
I could find a workaround by editing the global settings.py file and the global urls.py files:
---------- settings.py ----------
[ . . . ]
# User Logging in Settings
LOGIN_URL = '/login'
LOGIN_REDIRECT_URL = '/'
[ . . . ]
---------------------------------
and
------------ urls.py ------------
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'myserver.views.home', name='home'),
# url(r'^myserver/', include('myserver.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
#The following line will include the urls for the "mystartapp" application
url(r'^s', include('mystartapp.urls', namespace="mystartapp")), #Dirty trick
url(r'^mystartapp/', include('mystartapp.urls', namespace="mystartapp")),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
url(r'^login/$', 'django.contrib.auth.views.login'),
)
------------------------------
This way, thanks to the 10th line (the one with the #'Dirty trick' comment), everything that goes to the root of 127.0.0.1:8000/ will be redirected to the same set of urls as if I used 127.0.0.1:8000/mystartapp/, which combined with the LOGIN_REDIRECT_URL = '/' option in settings.py, will end up making the browser to redirect to 127.0.0.1:8080/mystartapp/index.html, after a correct login but that doesn’t seem “clean”.
Is there a better way of establishing a redirection to 127.0.0.1:8080/mystartapp/index.html? Is the dirty trick really a dirty trick or is it the way it’s supposed to work? Am I missing something here? (I’m pretty sure the answer to this last question is “Yes!”, though)
Thank you in advance.
Is there a reason why using
LOGIN_REDIRECT_URL = '/mystartapp/index.html'wouldn’t work in your case?Regarding the concept of apps, they are supposed to be independent bits of functionality (which is why they are sometimes labelled “reusable”). However, once you tie apps into a project, the goal is that they do work together at some point !
In the case of
contrib.auth, this reusability is expressed by the parameters you used (such asLOGIN_URLorLOGIN_REDIRECT_URL), which allows you to configure the behavior of the app so it works in your project.For instance, for a merchant side, you could use several apps to perform different actions related to your project:
django-solr)django-registration)The apps perform different bits of functionnality, but they all serve the same purpose and make up a project together.
If you need the apps to operate in a totally independent manner, they shouldn’t be part of the same project in the first place! (Although you could use app A in projects P and Q, and app B only in P, for example).