Rails and Django - Routing and Controllers (part 7/15)
URL Routing
URL routing is how the framework interprets an incoming request from the user's browser, and decides which function to direct it to, passing along any additional parameters from the user. The router allows “friendly URLs”, that are human-readable and don't have "those scary ?x=something blah blah things" in the strings (as someone I know put it)!
Rails
In Rails the config/routes.rb file defines the URL mappings. For example,
map.connect ':controller/:action/:id'
will route any URL in this format to the corresponding controller class, action method, and pass along the id as an argument. Thus, http://www.mysite.com/products/detail/123 goes to the ProductsController, “detail” action, for id = 123.
But you can change the mapping with new rules as needed, perhaps even change the url layout of the site without out changing any of the link_to, layout, form tags, etc in the code or templates.
Rails provide a URL generator (url_for method) so you do not need to hardcode real URLs in your code or templates. It uses the rules defined in routes.rb, so that logic is maintained in a single central location.
Django
In Django, the urls.py file defines the URL mappings. It uses standard regular expression (regex) syntax to parse the URL string and map it to your functions. For example,
(r'^(?P<object_id>\d+)/products/detail/$', 'store.products.view'),
will route any URL in format www.mysite.com/products/detail/NNN to the app “store”, view “products”, method “detail”, with argument id = NNN.
Note, you explicitly state the mapping from the URL strings to the corresponding class and method. The URL is completely decoupled from the structure of your app. Thus, for example, you could rename your app or classes without affecting the URLs the rest of the world uses to access your site. And you can provide multiple routes to the same functions, for example to support legacy URLs on a new site.
Django recently added a template tag to generate URLs based on the urls.py configuration.
Django uses an HttpRequest and HttpResponse objects to pass state through the system. HttpRequest contains metadata about the request (e.g post and session info). Each view is responsible for return an HttpResponse object (e.g includes the HTML body etc).
Opinion
Django's loosely coupled URL mapping and regex syntax is much more flexible and thus more powerful.
Unfortunately I was born missing the "regex gene"! For years I have tried to learn it, and failed pathetically. Sure, I can copy and make small changes from examples. But I do hesitate to put a key feature of my websites into my regex-challenged hands.
With regard to loose coupling in Rails, there is a workaround, by creating a dummy controller class which then makes the call to the actual one. Its really a kludge, but it I suppose it works.
Conclusion: Django's loosely coupled, regex based URL mapping wins against Rails' declarative mapping, 4 to 3.
| URL Routing | Rails | Django |
| URL Mapping | centralized, declarative (routes.rb) | distributed, regex (urls.py) |
| Reverse Mapping | complete | limited |
| MY RATING: (1=worst, 5=best) | 3 | 4 |
Controllers / Views
The controllers are the real meat of your application. Controllers define the action methods that handle specific requests from users. In Rails this is the Controller class; in Django its called Views. (And what Rails calls Views are equivalent to what Django calls templates).
Surprisingly, I don't have a lot to say here about controllers. Or else I'd have too much. That's because when you get into the controllers, you're really describing the programming language and framework's API, libraries and helper functions.
In both Rails and Django, the controller actions are usually pretty short, just a few lines of code. They grab some data via the Model class, perhaps do some processing, and package variables that are passed into the templates. They might also handle error conditions and exceptions (for example, in a shopping application, if the URL requests a product Id that doesn't exist in the database).
Rails scaffolding provides a quick and dirty automatic generation of the Controllers and Views for a model. These are intended as temporary placeholders while you incrementally build your app.
Django comes with built-in generic views. Not the same as Rail's scaffolding, these are handy for common actions such as list/detail interfaces, archive pages, and a set of view for creating, editing, and deleting objects. Of course, you still provide individual templates for any custom views.
In Django, you can augment views with “decorators”, a Python shortcut construct for specifying meta-attributes and contstraints. For example, a view method preceeded with @login_required will use the integrated authentication system to verify the user is logged in or he'll be redirected to a login page. In Rails you can accomplish the same thing with "filters".
Conclusion: I rate both a 3, and any real differences are covered in the other criteria.
| Controllers / Views | Rails | Django |
| MY RATING: (1=worst, 5=best) | 3 | 3 |
Oh give me a break. It's good enough for a nice overview, and very appreciated.




Rails and Django - Routing and Controllers (part 7/15)
Posted by: Hox on March 18, 2007 08:56 PM#