Django 1.8 | email as username

As you all know by default Django offers username and email separately. But if you are like me who wants to use email as the username and want to override the default behavior of django, there are few ways to do it
  1. Change the <username> label to 'email' using a custom form. But downside is username field is only 30 char long.
  2. Registering a custom user-auth-model, to the existing django-registration process. But downside is you can only do this before the first migration. 
  3. There are few modules available which extended username. So you can install that. But the downside is I was not sure if those modules are supported anymore.
  4. Building your own auth-model. But this requires lot of time.
  5. Making simple tweaks to the existing django-auth-model ( User) and use the existing django-registration ( I'm using django-registration-redux) to take care of everything.
There are pros and cons in every model, but l don't want to spend too much time on the login module because there are lot more fun things to do than spending time on a login module. So I'm going to Point-5 - simple tweaks to the existing django-auth-model.

  • Step-0: This is how the auth_user model looks before applying the below tweaks.

  • Step-1 : Create a new app called accounts.
python manage.py startapp accounts
  • Step-2 : Make the following change in <DjangoSite>/accounts/models.py
  • from django.db import models
    from django.contrib.auth.models import User
    
    
    #---- increase the size of the username field to 255 and make it as non-unique and nullable field
    username = User._meta.get_field('username')
    username.max_length = 255
    username.null = True
    username.blank = True
    username._unique = False
    
    #---- make email as unique and not-nullable field
    email = User._meta.get_field('email')
    email.blank = False
    email.null = False
    email._unique = True
    
    #---- add a custom_email_validator
    def custom_email_validator(p_value):
        if '@company.com.au' not in p_value:
            raise ValidationError('Only  emails are allowed')
        #end if
    email.validators += [custom_email_validator]
    
    
    #---- set email as the username identifier field and we dont need 'email' in required field-list anymore.
    User.USERNAME_FIELD = 'email'
    User.REQUIRED_FIELDS = []
    
    
    # Create your models here.
    class UserProfile(models.Model):
        user            = models.OneToOneField(User)
        profile_pic_url   = models.CharField(max_length=200, null=True)
        first_name      = models.CharField(max_length=100, null=True)
        last_name       = models.CharField(max_length=100, null=True)
        created_datetime    = models.DateTimeField(auto_now_add=True)
        modified_datetime   = models.DateTimeField(auto_now=True)
    
  • Step-3 : Make the following change in <DjangoSite>/settings.py
    • Add 'accounts' app to Installed_apps
  • Step-4 : run makemigrations and migrate.
  • python manage.py makemigrations
    python manage.py migrate
    
  • Step-5: auth_user after the above tweaks.




  • Step-6: Now if you see your registration form you can see all changes in effect .( Just one caveat. I hope you had already created your super-user. if not the default command <python manage.py createsuperuser> will throw errors. What I did is - created a normal user using this webpage and changed the is_admin, is_staff, is_active flag on the backend :) )


Comments

Popular posts from this blog

Tableau - Accessing Tableau's DB

react-bootstrap-table | header column alignment fix

Tableau : Convert ESRI shapes into Tableau Format