What is the recommended django project structure? - django

I haven't exactly found the answer to this, maybe there is no best one. Django docs are not clear on this thing.
I'm not sure what is a good practice to set up a django project. Sure I have re-usable apps. But I always need some glue-code.
I find myself always creating "core" app for each project, which usually serves homepape.
Then in project url config I do something like this:
(r'^/$', include(core.urls))
Is this the way to go? Or do you have a better idea?

I think it's a good idea to use a glue app/module that also contains further helper functions/reusable code (if any), however I'm not sure if that's the way the other djangonauts do these kind of stuff.
Also, in order to match the homepage I think that the correct regexp is r'^$'. With the above solution you propose, you'll have to be careful because every url defined in core.urls will be 'mounted' under your site's root directory.
Also, and for the case of the homepage I used something like this
(r'^$', 'apps.core.views.homepage')
just to distinguish this url. I guess it's just a matter of how one wants things organized.

Don't put the slash and the dollar. This is how I did it.
(r'^', include('core.urls')),
You're already on the right track. ;)

The approach you mention is a good one. I tend to stash away stuff like that into a views.py file in the root of the project. There is already a urls.py in the root folder.

Related

Is there an easy way to tell which URLs are unused?

I have a Django project which is entering its fourth year of development. Over those four years, a number of URLs (and therefore view functions) have become obsolete. Instead of deleting them as I go, I've left them in a "just in case" attitude. Now I'm looking to clean out the unused URLs and unused view functions.
Is there any easy way to do this, or is it just a matter of grunting through all the code to figure it out? I'm nervous about deleting something and not realizing it's important until a few weeks/months later.
The idea is to iterate over urlpatterns and check that the status_code is 200:
class BasicTestCase(TestCase):
def test_url_availability(self):
for url in urls.urlpatterns:
self.assertEqual(self.client.get(reverse('%s' % url.name)).status_code,
200)
I understand that it might not work in all cases, since there could be urls with "dynamic" nature with dynamic url parts, but, it should give you the basic idea. Note that reverse() also accepts arguments in case you need to pass arguments to the underlying view.
Also see: Finding unused Django code to remove.
Hope that helps.
You are looking for coverage, which is basically "how much of the code written is actually being used".
Coverage analysis is usually done with tests - to find how what percentage of your code is covered by tests - but there is nothing stopping you to do the same to find out what views are orphaned.
Rather than repeat the process, #sk1p already answered it at How to get coverage data from a django app when running in gunicorn.

How can I write a regex to match everything but a char?

I've switched in my wordpress blog from urls like this:
/blog/2012/01/01/how-to-build-a-website
To shorter urls like this
/blog/?p=123
Wordpress has a search engine who works like this
/blog/search/?s=how to build a website
And search for the s params.
I'm trying to use .htaccess Redirectmatch to redirect all the old urls to the search url with the title of the post as the s params.
So if the user serf to
/blog/2012/01/01/how-to-build-a-website
should be redirect to
/blog/search/?s=how to build a website
I've coded this
Redirectmatch blog/\d+/\d+/\d+/(.+) http://www.mysite.com/blog/?s=$1
But this regex grap the whole string after the last / within the - symbol inside it.
In this way if a user serf to
/blog/2012/01/01/how-to-build-a-website
Will be redirected to
/blog/search/?s=how-to-build-a-website
while I want the user redireced to
/blog/search/?s=how to build a website
How can I write the regex to do this?
EDIT:
Yes guys, I know that this kind of urls are ugly :) But I just would know how to do it, because behind this there are some technical issues I'm trying to solve..
Please don't do this. I know it can seem tempting to go for short URLs; after all, you get things like TinyURL and such. Isn't it better to have /blog/?p=123 than /blog/2012/01/01/how-to-build-a-website?
No. It's not.
The reason is because when someone posts a link to your blog article, the longer URL means something. It tells the person how old the article is. It gives the title. It helps people find your article; after all, the URL is given a lot of weight by Google when indexing your site.
URLs used to be built for computers. Something like /blog/?p=123 is perfect for computers; it's easy to parse, it doesn't require any extra database lookups. You can write two articles named "How to Build a Website" and the blog engine doesn't have to make sure it adds a -2 on the second one. It maps easily to the actual structure of files on the server, without making up structure in the URL.
But we've realized since that URLs can be built for humans, too. The URL /blog/2012/01/01/how-to-build-a-website has a form that can be easily understood by humans. Sure, it's a bit longer to type, but all the bits you're typing are easier, and most URLs are copy'n'pasted anyway or just clicked on. It's more work for the computer, sure, but it's worth it. It makes the Internet friendlier.
So I'm sorry, but I won't help you. :)

Django URL Aliases

I'm new to Django and I have a BIG problem. I don't like the "url pattern" philosophy of Django.
I don't want my pages to look like
http://domain.com/object/title-of-object
I want
http://domain.com/title-of-object
and of course I will have more than one type of object.
Is there an elegant way to achieve this with Django (not using hard-coded urls)?
Thanks!
Ever wondered that, if what you want to do seems so hard to acheive, you're doing it wrong? What is so wrong with /foo/name-of-foo/ ?
I'm trying to imagine your use-case and wondering if you need 'human' URLs for only a handful of pages. If so, it would work to go with the /foo/slug-for-foo/ approach but then use the django.contrib.redirects app to support hand-written URLs that redirect to the saner, more RESTful ones?
It is possible. You'll have to create one catch-all URL pattern, for which you'll create a view that will search all possible object types, find the matching one, and process and return that. Usually, this is a bad idea.

django internalization in urls? how to make urls like this: "en/articles" and "pt/artigos"...?

Hy!
I would need to make urls based on language.
Example:
If I had the language english and subcategory named "articles" then the url might be like this:
/en/articles/...
If the language were portuguese and subcategory already translated is "artigos" then the url will be:
/pt/artigos/...
How can I do it?
I must use the urls.py or some monkeypatches?
thanks
This features is already existing in the yet-to-be released version 1.4. You can read about it in the release note.
If your really need this feature, and no existing app feets your needs, you can still try to apply the corresponding patch yourself.
Django LocaleURL is a piece of middleware that does exactly this. The documentation can be found in the source, or online.
Edit: I read over the fact that you want to translate the url itself... I'm not aware of any piece of code that provides this. Perhaps you could extend the LocalURL middleware to take care of the translations for you. Say you have a regex match like (?P<articles>\w+), you could in the middleware determine which view you want to use. Something like the following mapping perhaps?
if article_slug in ['articles', 'artigos', 'article']:
article(request) # Call the article view
I've been using transurlvania with great success, it does exactly what you need and more, however i see that in the next Django release django-i18nurls will be included in django core so perhaps it would be better to learn that

Django's Satchmo and flatpages issue

I'm having a problem with configuring Flatpages in Satchmo. I've used them before, in a pure django app, but now it just doesn't work, returning 301 http error when I'm trying to enter a flatpage-configured site.
What I've done to configure it:
added the middleware "django.contrib.flatpages.middleware.FlatpageFallbackMiddleware" to MIDDLEWARE_CLASSES as last in the list,
configured example pages in admin module.
Simply what the docs say about flatpages config.
I'm feeling helpless. Don't know how could I debug this issue. Any thoughts on that?
And of course help appreciated.
Thanks to suggestion by Peter I've managed to narrow the problem to my urls.py file, for the satchmo shop.
The urlpatterns has only one entry:
(r'', 'django.views.generic.simple.redirect_to', {'url' : '/shop/'}),
This version does not work and moreover interfere with flatpages. But disabling flatpages from MIDDLEWARE_CLASSES and adding it to urls.py like the snippet below works:
(r'^(?P<url>.*)$', 'django.contrib.flatpages.views.flatpage'),
(r'', 'django.views.generic.simple.redirect_to', {'url' : '/shop/'}),
However next problem is with the redirection from / to /shop/. With the above config it results in infinite loop.
Perhaps you know the reason for that behavior (redirect overriding flatpage) and maybe You could suggest some working solution to this problem or what should be done with requests to /.
It returns 301? That's Page Moved Permanently (HttpResponsePermanentRedirect) and there are no references to that in the flatpages directory so I don't think it's coming from there. In fact there are only about 5 references to HttpResponsePermanentRedirect in all of the standard 1.1.1 release.
Possible approaches:
Comment out the FlatPages middleware and see if the error changes (I'm betting it won't).
Try changing the order of your MIDDLEWARE classes and see if things change.
When presenting a problem like this it's better to get very specific by showing the exact code from applicable portions of settings.py (or whatever) and by giving other things like precise URLs and the urls.py patterns you are trying to match.
Update:
OK, some random thoughts:
The pattern (r'^(?P<url>.*)$', 'django.contrib.flatpages.views.flatpage'), will match anything. Any patterns after it will never be seen.
flatpages doesn't work by being called directly, it does its magic in middleware. It looks for 404 responses (Page Not Found) and then looks to see if that path exists in its table. If so, it calls a view that renders the page, etc. etc. If it doesn't find a match it let's the 404 continue on through middleware processing.
The pattern (r'', 'django.views.generic.simple.redirect_to', {'url' : '/shop/'}), will match anything (I just tested it). If you want to match an empty path, use r('^$', etc.). This is the source of your infinite loop.
If you are new to regular expressions the Django urls.py file can seem like F*cking Magic. I recommend starting very simply and add one rule at a time. Do some quick tests to ensure that the new rule a) matches stuff you want it to match, and b) doesn't match stuff it shouldn't. In particular, make sure that some of the rules that occur later in the file are still reachable. In this case they wouldn't have been which should have raised a red flag.