Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change default django User model to fit my needs?

The default Django's User model has some fields, and validation rules, that I don't really need. I want to make registration as simple as possible, i.e. require either email or username, or phone number - all those being unique, hence good as user identifiers.

I also don't like default character set for user name that is validated in Django user model. I'd like to allow any character there - why not?

I used user-profile django application before to add a profile to user - but this time I'd rather make the class mimimal. But I still want to use the User class, as it gives me an easy way to have parts of site restricted only for users logged in.

How do I do it?

like image 800
kender Avatar asked May 22 '09 05:05

kender


3 Answers

Rather than modify the User class directly or do subclassing, you can also just repurpose the existing fields.

For one site I used the "first_name" field as the "publicly displayed name" of a user and stuff a slugified version of that into the "username" field (for use in URLs). I wrote a custom auth backend to allow people to log in using their "public name" or their email address, and I enforce the uniqueness of both of those at registration time. This plays nicely with other reusable apps and doesn't introduce extra tables or queries.

For another site I didn't want usernames at all, just unique emails. In order to satisfy Django's need for a unique username, I just hashed the email address and used that as the username (you have to base64-encode the hash to squeeze it under 30 characters). Custom auth backend to allow login with email.

If backwards-compatibility weren't an issue, there are a lot of improvements I'd love to see made to django.contrib.auth and the User model to make them more flexible. But there's quite a lot you can do inside the current constraints with a little creativity.

like image 185
Carl Meyer Avatar answered Oct 16 '22 20:10

Carl Meyer


I misread the question. Hope this post is helpful to anyone else.

#in models.py
from django.db.models.signals import post_save  

class UserProfile(models.Model):  
    user = models.ForeignKey(User)  
    #other fields here

    def __str__(self):  
          return "%s's profile" % self.user  

     def create_user_profile(sender, instance, created, **kwargs):  
        if created:  
           profile, created = UserProfile.objects.get_or_create(user=instance)  

post_save.connect(create_user_profile, sender=User) 

#in settings.py
AUTH_PROFILE_MODULE = 'YOURAPP.UserProfile'

This will create a userprofile each time a user is saved if it is created. You can then use

  user.get_profile().whatever

Here is some more info from the docs

http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users

like image 7
Raisins Avatar answered Oct 16 '22 20:10

Raisins


The Django User model is structured very sensibly. You really don't want to allow arbitrary characters in a username, for instance, and there are ways to achieve email address login, without hacking changes to the base model.

To simply store additional information around a user account, Django supports the notion of user profiles. While you don't need to rely on the built in support to handle this, it is a convention that is commonly followed and it will allow you to play nice with the reusable Django apps that are floating around in the ether. For more information, see here.

If you want to actually modify the core User model but also "play nice" with reusable apps that rely on it, you're opening a bit of a Pandora's Box. Developers make base assumptions about how the core library is structured, so any changes may cause unexpected breakage. Nonetheless, you can monkeypatch changes to the base model, or branch a copy of Django locally. I would discourage the latter, and only recommend the former if you know what you're doing.

like image 7
Daniel Naab Avatar answered Oct 16 '22 18:10

Daniel Naab