Django Authentication With Email Instead of Usernames

Posted: March 15th, 2010 | Author: Arif Harbott | Filed under: Django | Tags: , , , | No Comments »

A lot of the applications we build use email addresses instead of usernames. Personally I find it a lot easier to remember my email address than an ever growing list of usernames.

The way we do this is to write a simple custom auth backend in the following way:

1. In settings.py add the following lines (replace yourprojectname with the name of your app):

AUTHENTICATION_BACKENDS = (
    'yourprojectname.backends.EmailAuthBackEnd',
    'django.contrib.auth.backends.ModelBackend',
)

2. Create a file called backends.py and put it in your root folder (i.e. the same folder as settings.py)

from django.contrib.auth.backends import ModelBackend
from django.contrib.admin.models import User

class EmailAuthBackEnd(ModelBackend):
    def authenticate(self, email=None, password=None,**kwargs):
        try:
            user = User.objects.get(email=email)  

            if user.check_password(password):
                return user
            return None
        except User.DoesNotExist:
            return None

3. In your views import the authenticate back end and then call the authenticate function:

from django.contrib.auth import authenticate
....
user = authenticate(email=email, password=password)

Format DateTime in Django Admin

Posted: March 10th, 2010 | Author: Arif Harbott | Filed under: Django | Tags: , | 6 Comments »

If you are trying to format a DateTimeField() field in the Django admin you may find it harder than you think. You would think that the DATE_FORMAT and DATETIME_FORMAT in settings.py would apply to the admin BUT it only applies to date formatting in the template.

At present there is no easy way to format the date but the following example of one method of how to do it:

class News(models.Model):
    headline = models.CharField(max_length=100)
    date = models.DateTimeField()
    article = models.TextField()
    published = models.BooleanField()

class NewsAdmin(admin.ModelAdmin):
    list_display = ('headline', 'format_date', 'published')

    def format_date(self, obj):
        return obj.date.strftime('%d %b %Y %H:%M')
    format_date.short_description = 'Date'

object instance / type / typeof

Posted: March 10th, 2010 | Author: Davo | Filed under: Django | Tags: , , , | 1 Comment »

In some circumstances it is useful to know what type() / instance the object is.
Python provides 2 useful built in functions which can be handy for this kind of operations.

>>> from apps.deals.models import Deal
>>> deal = Deal.objects.get(id=1)
>>> type(deal).__name__ # retrieve the name of the class
'Deal'
>>> type(Deal()).__name__ # same
'Deal'
>>> type(str()).__name__ # internal python string class.
'str'

Now lets see how the isinstance() works

>>> isinstance(deal, str) # is 'deal' instance of 'str' ?
False
>>> isinstance(deal, Deal) # is 'deal' instance of Deal ?
True
>>>

Multiple Object Does Not Exist

Posted: March 9th, 2010 | Author: Davo | Filed under: Django | Tags: , , | No Comments »

The DoesNotExist exception is raised whenever the lookup with get() fails.
To catch this exception simply do this:

from myapp.models import User
try:
    user = User.objects.get(id=666)
except User.DoesNotExist:
    print 'Seems that there is not a user with id 666'

The DoesNotExist is inherited from ObjectDoesNotExist.
Knowing this we can catch an exception for multilple get() calls.

A simple example:

from django.core.exceptions import ObjectDoesNotExist
try:
    user = Entry.objects.get(id=1)
    blog = Blog.objects.get(id=666)
except ObjectDoesNotExist:
    print "Either the User or the blog doesn't exist."

Filtering Foreign Key Choices

Posted: March 9th, 2010 | Author: Arif Harbott | Filed under: Django | Tags: , , , | No Comments »

A common question I get asked is how do you filter the auto generated foreign key select box in the Django. The answer is very easy you use the limit_choices_to method, which can be found on the Model Field reference page on the Django site.

Here is an example.
You want to limit the author of the news article to only show those users who are in the group admin (which is id: 1). You would use, limit_choices_to={‘groups__in’: [1]}

class News(models.Model):
    headline = models.CharField(max_length=100)
    author = models.ForeignKey('users.UserProfile', limit_choices_to={'groups__in': [1]})
    date = models.DateTimeField()
    article = models.TextField()
    published = models.BooleanField()

Now when you edit a news article only the users who are in the admin group will be shown.

You can also use a Q object instead of a dictionary, which I will cover in another article.