I started a draft of a Rails vs Django post a few weeks ago. It has been something I have been meaning to do as Django is turning into the designer’s language of choice. This is absurd to me, Ruby is a far more aesthetic language. I have many arguments as to why I think Rails is far superior to Django. It is proving tasking not to post all my notes. I will give arguments on both sides (if you do Django and have something to contribute, please contact me).
I will start this series off with a very simple comparison of the codes. Taking the number #2 Top-rated snippet and then convert it to Rails code.
Thanks on this series go to Sandro Turriate, Cal Henderson and Jeff Croft
Edit- After talking with a friend, who was apparently offended by this post, I thought I’d go into more detail about this. This series of posts were not meant to offend anyone but merely give light to other languages. My friends that have forayed into Python have been both designers and developers. This post was to the designers out there who have chosen Python. I wanted to show them that there is still better. Even if they kept with Python, I wanted to show them where Django could improve so they could make their life easier even if they stick with their language. When designing, I love hearing what I do wrong, so I can do better. Same goes for programming. Others apparently do not share this with me.
Wow. Never looked at Django before. That snippet is unreadable. Rather after reading the ruby snippet I was amazed the snippet was for authentication and not sending email or some other back-end task.
The Ruby bit is more readable and more intention revealing.
Seems like the author of that snippet has been taking ReinH's advice about unfactoring for job security.
Good stuff, keep it coming, Zach.
Rick
The Django code example doesn't equal to RoR one. In Django code there is incoming 'username' validation with regular expression but in the RoR one there is no such functionality.
Then in D-code there is using of standard User model and standard user authentication pipeline. And what is 'User' in R-code? Where it has come from?
Alex: What do you mean, “what is 'User' in R-code?' The code itself is part of the User class definition (see where it says 'class User < ActiveRecord::Base').
The Django code might bring in all sorts of existing functionality with those imports, but it's premature to say that the snippet as it stands provides something above and beyond the Ruby/Rails code. The appropriate response would be to provide a testcase that passes for one and not the other.
Good post Zach. Thanks.
Could you please clarify the statement:
“I have many arguments as to why I think Django is inferior to Ruby.”
Did you mean to say “Python is inferior to Ruby” or “Django is inferior to Rails”?
I agree with Alex, these code snippets are not the same. Django has a built in authentication mechanism, and this is providing a custom implementation of that. It is hard to compare these apples to apples. So assuming Ruby and Rails had a authentication system that worked like Django, it might look like this:
Throw this in lib/email_re.rb:
EMAIL_RE = /A([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})/i
And this wherever backends would go:
require 'email_re'
#I assume this is monkey patching a BasicBackend class
#that is already defined in Django?
#Or else you would just define both methods in EmailBackend?
class BasicBackend
def self.get_user(id)
User.find(id)
rescue ActiveRecord::RecordNotFound
nil
end
end
class EmailBackend < User
def self.authenticate(username, password)
if EMAIL_RE.match(username)
user = find_by_email(username)
return nil unless user
else
user = find_by_username(username)
return nil unless user
end
user if user.check_password(password)
end
end
From reading the comments on the Django snippets site, it looks like there are better ways of doing this even in Django. But I'm glad Ruby on Rails doesn't have an authentication system that works like Django's :). Instead we have restful_authentication, you just override User#authenticate in a way similar to what you have done. I think this way is a little closer to the Python/Django example:
require 'email_re'
class User < ActiveRecord::Base
def self.authenticate(login, password)
user = if EMAIL_RE.match(login)
find_by_email(login)
else
find_by_username(login)
end
return user if user and user.check_password(password)
end
end
Assuming this comment system has destroyed the formatting, see http://gist.github.com/12536
As much as I hate to say this (because it involved me reading Python closely enough to comprehend it), the two examples do not seem to be exactly equivalent. The Django one appears to check if the given username is “emaily” and, if so, only searches for a User with that e-mail value, otherwise getting a User with that username value. The Rails one, on the other hand, indescriminently checks for a User with the given username as an e-mail and, if not found, username.
And there seems to be a typo (or a copy/paste-o) at the beginning of the Django example, in the first import line.
Thank you all. I have made some edits to clear the post up
Shouldn’t you also include the implementation of the Rails check_password method, or are you assuming this is included in a plugin?
This series might work better as aesthetic code golf, i.e. find a Django developer who would take your challenge on a piece of well-written, good-looking Rails code and try to do the same thing in Django (or vice versa).
Django definitely has some great features, but my theory is that it has been more readily endorsed by designers because of other influential designers who have endorsed it and also because of the core team’s endorsement of web standards, not because of inherent design-related features of the language or framework.
A default installation of Rails still uses inline Javascript with impunity and takes a laissez faire attitude toward web standards, leaving it to the developer to choose (which some people see as a good thing).
I’ve done a fair bit in both Rails and Django. While Rails (or the Ruby language to be more specific) does have some syntactic niceties that aren’t available to Django/Python, this comparison just isn’t valid.
The Django code snippet is extending the built-in Django authentication backend - not just adding an authenticate method to the User model as the Rails example shows. The Django example also provides a measure of error handling that’s missing from the Rails example.
I won’t argue that Rails/Ruby can be more concise than Django/Python. But only part of that is due to the language. You also must take into account the difference in development philosophies between the two frameworks/languages.
Django/Python places a high value on explicitness, while Rails/Ruby is perfectly comfortable with hiding some implementation detail in favor of code aesthetics and developer convenience.
I’m pretty new to Django and Python, but this comes to mind:
def authenticate(request, username, password):
user = email_re.search(username) and get_object_or_404(User,email=username) or get_object_or_404(User,username=username)
return user.check_password(password) and user or None
I’m pretty new to Django and Python, but this comes to mind:
def authenticate(request, username, password):
user = email_re.search(username) and get_object_or_404(User,email=username) or get_object_or_404(User,username=username)
return user.check_password(password) and user or None
Thursday I was searching for sites related to Viagra and specifically lipitor viagra and I found your blog. Thanks for the content.