Dynamically reload the URLConfs for a running site - python

I have a django site. Like all standard sites, it uses URLConfs to associate URLs with views. However, in addition to that, I have some URL configs which I dynamically generate from data in the database. Everything works as I would like it.
Is it possible to reload all the URLConfs while the site is running, from code? In case someone updates the database and change some of the URLs in the site, I would like to trigger a "rediscovery" of all the URLs. This would cause my code to dynamically re-create the URLs from the data in the DB.
Currently, the generated URLs can be anywhere in the URL hierarchy. They are not all under one prefix, such as /dynamic/ or such. However, if this is absolutely necessary to do what I need to get done, I can place all the dynamic URLs under one prefix.
Some downtime is allowed for the site while the rediscovery of URLs take place.
How would I trigger such a reloading of all the URLConfs?

Your question starts from a premise that most Django programmers wouldn't accept: that you can or should create URLs dynamically from the database. If you're doing that, you're doing it wrong.
Your URL patterns are part of the code, not the data. Obviously, the URLs themselves are formed by combining the patterns with the data - eg foo/<slug>/bar/, but this doesn't need reloading when new slugs are added because it is resolved by the view, not the URL processor.

import sys
from django.conf import settings
from django.core.urlresolvers import clear_url_caches
clear_url_caches()
reload(sys.modules[settings.ROOT_URLCONF])

Related

Can I tell where my django app is mounted in the url hierarchy?

I need to redirect my clients to another endpoint in my django app. I know I can use relative urls with request.build_absolute_uri() to do this, but I am searching for a generic solution that doesn't require the redirecting handler to know its own place in the URL hierarchy.
As an example, I have handlers at the following two URLs:
https://example.com/some/other/namespace/MY_APP/endpoint_one
https://example.com/some/other/namespace/MY_APP/foo/bar/endpoint_two
Both handlers need to redirect to this URL:
https://example.com/some/other/namespace/MY_APP/baz/destination_endpoint
I would like for endpoint_one and endpoint_two to both be able to use the exact same logic to redirect to destination_endpoint.
My app has no knowledge of the /some/other/namespaces/ part of the URL, and that part of the URL can change depending on the deployment (or might not be there at all in a development environment).
I know I could use different relative urls from each endpoint, and redirect to the destination URL. However, that required that the handlers for endpoint_one and endpoint_two know their relative position in the URL hierarchy, which is something I am trying to avoid.
After doing more research and talking with coworkers, I realized that reverse does exactly what I need.

Multiple urls mapped to same function

I have this url in my urls.py:
url(r'^showrooms/', include('apps.showrooms.urls')),
and i want to have another url like this(i.e w/o 's' of showrooms)
url(r'^showroom/', include('apps.showrooms.urls')),
but having two urls like above results in two urls mapping to same data which is not good from seo perspective.So the solution is to redirect showroom/ urls to showrooms/ urls, but how do i get to this as showrooms/ is pointing to set of urls in apps folder ?
If you want to keep it close to django you can use the redirect shortcut as found in the documentation here: https://docs.djangoproject.com/en/dev/topics/http/shortcuts/#redirect
Otherwise this is more like a webserver question, for apache there is mod_rewrite in which you can 301 redirect, and nginx has the rewrite directive which should suit your needs just fine!

can i do this in django? admin with pages as models vs cms?

Today I was just in the train and had some spare time to think about django cms and admin.
Can I define pages as models like this:
class ArticlePage(models.Model):
slug = models.TextField()
content = models.TextField()
online = models.BooleanField()
etc...
and then edit this model in django admin? Because, i think, django cms will also work,more or less, in this way, right?
will this be fine?
Where i am stuck is that i dont know how to set dynamic urls for those pages, because i need to touch urls.py for this, right?
Theoretically you can create a view which has a wildcard as the URL. And then have the view lookup the various actually used URLs in the ArticlePage.
def pageView(request, url):
page = ArticlePage.objects.get(slug=url)
...
return page.content
With the URLs specified as:
urlpatterns += patterns('articles.views',
(r'^(?P<url>.+?)/$', 'pageView'),
) #Catch all URLs not yet matched and attempt to find them in the database.
at the end of your urls.py.
And then you can use an HTML editor of some sort to create the actual content and whatnot.
So it is possible. However the question is do you want to?
It is possible to create a few of the pages on a website completely from scratch and storing the HTML in a database. Think small pages which are rarely updated but if updated change rigorously.
However, generally speaking a website has some structure. Something like blog posts, comments, polls, user registration and other interactive pages. Those pages cannot be described in a database field holding HTML.
Although if you do actually manage to do all that then I fear for your sanity because it must have been a painful and awkward road.
Hope this helps.
Update:
If you want to show a static HTML only page you normally just refer to them directly from the urls.py. Generally very few HTML is directly stored in databases. Most often you just store data in the database. If HTML is heavily being modified/saved/created/served from the CMS you just store it as an HTML file somewhere on the webserver.
Although one can certainly think of reasons to put HTML pages in the Database there is an equal many reasons as to why you shouldn't. It all comes down to the specifics of the problem.
E.g. if you allow a user to create a comment with links/boldface/italics etc. you can save the word or //word// in the db and parse it every time. Or you can parse it once and just store the HTML in the database so you don't have to parse it every time.
Same goes for larger pages although they generally have too much markup to be hand typed via the CMS every so often.
As for serving an HTML page directly via urls.py:
E.g.
from django.views.generic import TemplateView
urlpatterns = patterns('',
(r'^foo/$', TemplateView.as_view(template_name='foo.html')),
)
Source: How do I go straight to template, in Django's urls.py?

Django Redirect URL

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.

Link to get http response works just once in django

I am having problem to get graphical result for second time either it be for a database query or two or more queries. For first time result is given as desired immediately but thereafter browser just says 'Connecting'. For example after http://localhost:8000/graph/ gives pie-chart for first time it does not give the pie-chart again when the same link is hit and also any other similar link http://localhost:8000/graph2/ doesnot work. The latter link would have worked if http://localhost:8000/graph2/ was hit first after execution of program.
In urls.py links are given as:
url(r'^graph/', graph, name = 'ngraph'),
url(r'^graph2/', graph2, name = 'ngraph2'),
Directory structure looks:
Detail code is given HERE.
Two options:
In your urls.py, add a separate pattern object with the prefix set as the views of your app. That would be like urlpatterns += patterns('welcome.views', url(r'^graph/', ...)). Rest should be as it is.
Dont change urls.py. Instead refer to the complete path in the template starting from your app. In your case that might be {% url welcome.views.ngraph %}.
Since you mentioned that GET is not being served at all, it is quite possible that the server cant locate (map) the url to the function.
In an ideal situation, you should import welcome.views instead of using from .. import * and polluting the urls.py globals. Use the complete path in the patterns object. This way you wont need separate patterns objects for different apps. This would make a lot of sense in a bigger project with more applications. But in any case, this is the standard practice and is encouraged.
Do post your result.

Categories