Django Redirect URL - python

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.

Related

Django - Managing page content in Django Admin

I'm new to working with Django and am developing for a client who wants to be able to change page content in the Django Admin. They need to be able to change the html of the index page without editing the files on the server.
I know about flatfiles but I'm not sure that's completely what I'm after as I can't display stuff such as Django forms for example.
EDIT: Kind of like how a CMS works but without the users/group stuff and be able to use Django View modules such as forms.
Any advice?
Thanks
Honestly, the scope of what you're looking for is too huge to cover in this format. There's a number of ways this could be done, but they're all going to require some work and customization based on the client's needs.
Flatpages could work if you allow HTML content and make sure the content is rendered as "safe" in the template. This really only covers the "content" area of the site, though. It wouldn't be wise to use flatpages for an entire site template, including header, sidebar, footer, etc.
You could create editable areas. So, you actually create models for things like headers, sidebars, footers, and modules within those areas, and then just pull them into the template as needed. Then, the client is only editing pieces of the template instead of responsible for the whole HTML document.
Forms are going to be a challenge, because they require backend-processing that requires a connected view. The client won't be able to just arbitrarily drop in some form code and have a form. But, you could use a third-party service form forms and just embed them in the available content regions. Or, there's a couple of django apps that try to implement a type of "form builder" in the admin. That might somehow let the client add a form via something like the shortcodes used in Wordpress, but you'd likely have to lay down some infrastructure to make that work.
At a certain point, stuff like this reaches a point of diminishing returns, though. The only way to allow total customization of the template is to drop down into the actual physical file and make changes there. You can make certain things easier for the client, but ultimately, they either need to scale back their customization needs or deal with the fact that they'll have to work with the filesystem.
I don't believe that is possible at this time. Of course you can edit your models but templates, I think not.
I would find out how much they need to change? If they plan a complete redesign every week then you're still looking for an answer. If they just need a dynamic front page then you can split it up into variables and let them edit sections of html. Much safer and less prone to breaking the html.

Make Django URLs work with or without /

I have a django app that has / at the end of every URL conf. Example:
# user home page
(r'^home/$', 'user_home_page'),
However, I'm noticing this is causing a ton of redirects on my server, because when people dont add the /, it redirects them. Is there any way to have it accept both without a redirect except doing:
# user home page
(r'^home$', 'user_home_page'),
(r'^home/$', 'user_home_page'),
or should I avoid URL confs like that?
While you can accept both without doing a redirect by using:
(r'^home/?$', 'user_home_page'),
It is not best SEO practice because it will look like you have duplicate content and your hits will be split between the two pages.
You could modify your APPEND_SLASH Django setting, I haven't used it before.
You may be wondering what happens if someone requests the URL /hello
(that is, without a trailing slash). Because our URLpattern requires a
trailing slash, that URL would not match. However, by default, any
request to a URL that doesn’t match a URLpattern and doesn’t end with
a slash will be redirected to the same URL with a trailing slash.
(This is regulated by the APPEND_SLASH Django setting, which is
covered in Appendix D.)
This was taken from http://djangobook.com/en/2.0/chapter03/
The patterns are Python regular expressions. How about:
(r'^home(/?)$', 'user_home_page'),
should I avoid URL confs like that?
Yes. Django already handles this for you.
See this: https://docs.djangoproject.com/en/1.3/ref/middleware/#module-django.middleware.common
If APPEND_SLASH is True and the initial URL doesn’t end with a slash,
and it is not found in the URLconf, then a new URL is formed by
appending a slash at the end. If this new URL is found in the URLconf,
then Django redirects the request to this new URL. Otherwise, the
initial URL is processed as usual.
Use Django REMOVE_SLASH middleware instead.
https://gist.github.com/2204099
https://gist.github.com/gists/2204099/download
You need to ensure your application uses / consistently, make a choice which to use, and 301 redirect the rogue variation to the correct canonical one.
There should only be one version of a page, and the correct solution is in most cases to 301 redirect to the canonical version.
In some situations with additional paramenters for tracking you should also define a canonical in the head.
By using consistent URLs within your APP and out on the web in links pointing back to your app, you then won't have lots of redirects.

Dynamically reload the URLConfs for a running site

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])

Does Django have a built in way of getting the last app url the current user visited?

I was hoping that Django had a built in way of getting the last url that was visited in the app itself. As I write this I realize that there are some complications in doing something like that (excluding pages that redirect, for example) but i thought I'd give it a shot.
if there isn't a built-in for this, what strategy would you use? I mean other than just storing a url in the session manually and referring to that when redirecting. That would work, of course, but I hate the thought of having to remember to do that for each view. Seems error-prone and not very elegant.
Oh, and I'd rather not depend on server specific referral environment variables.
No, there is nothing like that built in to Django core (and it's not built in because it isn't a common usage pattern).
Like Javier suggested, you could make some middleware which does what you want. Something like this:
class PreviousURLMiddleware(object):
def process_response(request, response):
if response.status_code == 200:
request.session['previous_url'] = request.get_full_url()
return response
This middleware would have to go after SessionMiddleware in your settings to ensure that the session will be updated after this (the docs have a pretty picture explaining why this is).
you can just write a middleware that does exactly that, no need to repeat logging code on every view function.

Pylons/Routes rewrite POST or GET to fancy URL

The behavior I propose:
A user loads up my "search" page, www.site.com/search, types their query into a form, clicks submit, and then ends up at www.site.com/search/the+query instead of www.site.com/search?q=the+query. I've gone through a lot of the Pylons documentation already and just finished reading the Routes documentation and am wondering if this can/should happen at the Routes layer. I have already set up my application to perform a search when given www.site.com/search/the+query, but can not figure out how to send a form to this destination.
Or is this something that should happen inside a controller with a redirect_to()?
Or somewhere else?
Followup:
This is less an actual "set in stone" desire right now and more a curiosity for brainstorming future features. I'm designing an application which uses a Wikipedia dump and have observed that when a user performs a search on Wikipedia and the search isn't too ambiguous it redirects directly to an article link: en.wikipedia.org/wiki/Apple. It is actually performing an in-between HTTP 302 redirect step, and I am just curious if there's a more elegant/cute way of doing this in Pylons.
You can send whatever content you want for any URL, but if you want a particular URL to appear in the browser's address bar, you have to use a redirect. This is independent of whether you use Pylons, Django or Rails on the server side.
In the handling for /search (whether POST or GET), one would normally run the query in the back end, and if there was only one search result (or one overwhelmingly relevant result) you would redirect to that result, otherwise to a page showing links to the top N results. That's just normal practice, AFAIK.
HTML forms are designed to go to a specific URL with a query string (?q=) or an equivalent body in a POST -- either you write clever and subtle Javascript to intercept the form submission and rewrite it in your preferred weird way, or use redirect_to (and the latter will take some doing).
But why do you need such weird behavior rather than just following the standard?! Please explain your use case in terms of application-level needs...!

Categories