This is a kind of want-to-know itch. Many questions here ask how to replace the default Django homepage (e.g. ). I understand that issue. What I'm curious to know is how the default page is rendered when a new project is created (i.e., in debug mode). Even though my question is not as directly practical as knowing how to replace the default homepage, I have the feeling that if I figure it out, I may understand how Django works a bit better.
I would expect it to be in the default urls.py file, but the only entry by default in urlpatterns of urls.py is path('admin/', admin.site.urls). My first naive expectation would be an entry in urlpatterns that you could remove or comment out. Since there's nothing there besides admin/, I'm guessing there's some other built-in app or middleware that specifies the default homepage, but I don't know where to look.
Here's my progress in understanding this so far:
Commenting out DEBUG=True in settings.py causes the default homepage to no longer appear.
I've seen this documentation about how Django processes requests, which mentions middleware that can set the urlconf attribute on a request that changes the default, ROOT_URLCONF.
So far Django has been pretty straightforward, but this seems like something magical, so I'm trying to figure out what's going on behind the scenes.
I appreciate the help!
The relevant code is here. Django basically has a special case for when no matching URL is found in the URL configuration, and the requested path is /, and there is only one entry in the URL configuration.
In that case it loads a default_urlconf which renders that welcome template in place of a regular 404 response.
This is called from inside the technical_404_response function, which is only called when DEBUG=True.
Related
I have an old (Django 1.11) over complicated Django application with overlapping and funnily ordered url matching rules and I want to update it to newer Django versions and to simplify / refactor.
For better understanding Id' like to navigate through the application (manually) and retrieve some traces
Would it be possible to achieve following without having to add log statements in every view.
I'd like to get traces telling me which rule was picked by the url dispatcher (and if possible, but not really necessary), which view with which parameter was called.
I'm for example sure, that some rules can just be deleted as they're no more used.
Example:
If I had following (not complicated with non overlapping rules) url dispacher rules.
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^app1/', app1.views.top_view),
url(r'^app1/a', app1.views.a_view),
]
and I acessed http://myserver/app1. I'd like to have a trace telling me,
that http://myserver/app1 triggered rule ^app1/ and (not so important) view app1.views.top_view will be used to handle the request.
midllewares, decorators, monkeypatches, whatever will do as long as I don't have to change all individual rules and all views to get my traces.
Even a considerable performance hit is not an issue this is for debugging
P.S.
I am aware of the django-extensions module and the management command show_urls.
This is already helpful, but for more complicated urls showing up in my app I'd like to have the logging.
You may have to upgrade to 2.2 first, or backport this commit else you can't get information from the router about the exact match it has used to resolve the request URI.
That said, it should be done in middleware during request phase. The ResolverMatch instance is available in the WSGIRequest as request.resolver_match. Using the fix above, it's trivial to add a log to each request.
If you cannot backport or upgrade, there is a way to do it, which basically involves building a cache on start up of all known urlconfs and then matching each one and I've done it at some point, yet don't have it laying around any more. You basically have to do the work of URLResolver.resolve() and then add the route to it, when it creates the ResolverMatch instance. Hopefully this helps you get started.
I am using django.views.i18n.set_language() redirect view and HTML form where user can choose language.
I am doing everything as it's described in Django documentation for i18n translation .
The only difference that I made is that within HTML form I changed value of next parameter from {{redirect_to}} to {{request.get_full_path}}
Anyway, It worked completely fine while I was testing it locally. I could select different language and it would reload current page but with different language.
Now I put application on VPS where I use Gunicorn as application server and Nginx as web server. Now when I select different language it still changes it but it always redirect me to to home page / (site root).
I have no idea why is that happening now and how to change it. I want that he reloads the same page again instead of redirecting me to the / always. Anyway, at translation still works fine.
Thank you for your replys
Kind regards
Wander Nauta answered it in the comments
Are you sure request.get_full_path is available in the template?
You need to add django.core.context_processors.request in your template context processors settings, which is not there by default.
I was poking around my friends project and as I looked through the urls.py file i noticed this:
url(r'^apply/$', contact.as_view(), name='careers_contact'),
I just recently learned about class based views, and it all makes sense to me except for the last bit name='careers_contact'. I also can't seem to find the meaning of this online.
Can someone shed light on what this is, where that name lives, and what its doing?
url() name parameter
"What is it? Where does it live?"
url() is simply a function that returns a django.core.urlresolvers.RegexURLPattern object, so passing in a name='careers_contact' argument sets name for that object. None of that is really relevant until this url(...) is placed into a URLconf.
THEN, if we need the URL of a view, we can now get it by passing that name into {% url 'careers_contact' %} in templates or reverse('careers_contact') in code and on the backend those functions will use the name to map back to the correct URL.
Why do we need it?
We can reverse the Python Path to get the URL (ex. reverse(blog.views.home) ), so what's the point in using name?
URL Naming and Namespacing allow for 3 things:
A simple way to reverse URL match Class-Based Views. Though it is possible without it.
A way to distinguish URL patterns using the same view and parameters.
A way to differentiate URL names between apps.
(Click the links for an example of the issue and how naming/namespacing solves it)
The reason they probably added a namespace for the URL is so that they can do reverse namespaced URL.
For example in a template somewhere, you will probably see something like:
Click me!
I am new to Django, and i am now trying to use the HttpResponseRedirect() function. But I am so confused that if I use it like HttpResponseRedirect('good/'), and the current page is '/bad/', it can only be redirected to '/bad/good/', which is an url of current page appended with the url value from the HttpResponseRedirect() function. I tried to search google, and could not find any solution.
How can I redirect to the page with specific url? For example, HttpResponseRedirect('/good/') to /good/ rather than /bad/good/ ?
Surely you must see that there's a difference between 'good/' and '/good/'? The former will always add itself onto the existing page, whereas the latter will start from the root. This is basic web behaviour, and nothing to do with Django.
In any case, you should never hard-code URLs like that, but should use Django's URL-reversing functionality to calculate the URLs dynamically.
If you want to redirect to urls in your domain, you can use redirect. You can use redirect to view with by using patterns in your urls.py file or to any urls you 'd like. Although I strongly encourage the usage of views as indicates the different tutorials available on their website.
Better check out django documentation that is one of the most complete out there (to my humble opinion)
/edit for lack of clarity indeed.
I am using Lighttpd and Django. I have configured my Lighttpd server to pass all the requests ending with ".psp" extension to Django.
My startup page is a page served through Django, which is accessed as "http://192.168.1.198/home.psp". I want to enable the user to browse this page without writing "home.psp" explicitly in the url i.e. using "http://192.168.1.198"
Is this possible?
Thanks for any help in advance.
I think you're confusing concepts here between the "old" method of having individual files represent web pages which themselves contain code that is passed off to an interpreter before being sent in a response to how django/frameworks work.
If you're familiar with apache, imagine django as in part taking on the role of mod_rewrite. Django, and other frameworks, have what's called a dispatcher, or routing, mechanism.
Basically, they subscribe to the MVC pattern that says you should separate out the model, controller and view (in django parlance, model, template and view).
Now what then happens is you have a file called urls.py in django, which contains a list of routes (urls) and names of methods (usually contained in views.py) which handle them. Here's an example:
urlpatterns = patterns('',
url(r'^dologin$', 'testapp.views.auth_login', name="auth-login-uri"),
url(r'^doopenidlogin$', 'testapp.views.auth_openid_login', name="auth-openid-login-uri"),
url(r'^dologout$', 'testapp.views.auth_logout', name="auth-logout-uri"),
url(r'^login$', 'testapp.views.loginform', name="login-form"),
url(r'^openidlogin$', 'testapp.views.openidloginform', name="openid-login-form"),
url(r'^$', 'testapp.views.index', name="index"),
)
Here testapp is a python package, views.py is a python file and index is a django view. The url is constructed from regex, so I can have whatever I want as the url, much how stackoverflow urls are formed.
So basically, you never need file extensions again. I'd strongly suggest getting a good book on django - there are a few around.
What you might be looking for is the index-file.names directive in Lighty's configuration file. Just add "home.psp" to the list in your configuration file, and Lighty will look for it when no filename is specified.
I solved the problem myself. Here is what I did:
I had to add a statement inside url.rewrite-once block of lighttpd's configuration file like:
url.rewrite-once = (
"^(/media.*)$" => "$1",
"^(/static.*)$" => "$1",
"^/favicon\.ico$" => "/media/favicon.ico",
"^(/)$" => "/my_project_dir/home.psp",
"^(/.*)$" => "/my_project_dir$1",
)
Apart from this, I added the following line in my urls.py:
(r'^$',my_index_view_name),
Hope this helps someone in the future. Thanks everybody for your replies above. Cheers!