0
Two Scoops of Django
Chapter 16 - Dealing with the User Model

Alfred
When you check out
your user model…
or…
How it authenticates…
login

Authentication
Backends

authenticate

Model.User
Model.UserManager

pass

User
View

you kno...
Basic
From Django 1.5 onwards, the official preferred way to attach ForeignKey, OneToOneField, 	

or ManyToManyField to Use...
To customize your user
table, there are 3
options...
Warranty
We suggest that you carefully try out option #1
below, as it should work with a minimum of effort.
For Django 1.5...
Option 1 - Link back
You continue to use User (called preferably via
django.contrib.auth.get user model()) and keep your r...
Option 2 AbstractUser
Choose this option if you like Django’s User model fields the
way they are, but need extra fields	

!f...
Option 3 - Subclass
AbstractBaseUser
	


AbstractBaseUser is the bare-bones option with only 3 fields:
password, last login...
Option 3 - cont.(1)

	


1. Start from model.	

2. Model.UserManager create User -> override it to create
TwoScoopsUser	

...
Option 3 - cont.(2)
Implement usage functions…
def get_full_name(self): return self.email	

!
def get_short_name(self): re...
Option 3 - cont. (3)

	


Let’s write Model.UserManager to create TwoScoopsUser
class TwoScoopsUserManager(BaseUserManager...
Option 3 - cont. (4)

	


Let’s write Model.UserManager to create TwoScoopsUser
!
def create_superuser(self, email, favori...
Option 3 - Let Admin
show your data.
	


Basically, override contrib.auth.admin …
class TwoScoopsUserAdmin(UserAdmin):	
# ...
Option 3 - Let Admin
show your data. (2)
	


Implement your forms
class TwoScoopsUserCreationForm(UserCreationForm):	
"""A...
Thanks
Two scoopsofdjango ch16   dealing with the user model
Upcoming SlideShare
Loading in...5
×

Two scoopsofdjango ch16 dealing with the user model

807

Published on

A simple presentation for the book "Two Scoops of Django" Ch 16

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
807
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
9
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Two scoopsofdjango ch16 dealing with the user model"

  1. 1. Two Scoops of Django Chapter 16 - Dealing with the User Model Alfred
  2. 2. When you check out your user model… or…
  3. 3. How it authenticates… login Authentication Backends authenticate Model.User Model.UserManager pass User View you know, the best way is to trace the python source code. backends: contrib.auth.backends.py model: contrib.auth.models.py admin(user view): contrib.auth.admin.py • • •
  4. 4. Basic From Django 1.5 onwards, the official preferred way to attach ForeignKey, OneToOneField, or ManyToManyField to User is as follows: from django.conf import settings from django.db import models ! class IceCreamStore(models.model): owner = models.OneToOneField(settings.AUTH_USER_MODEL) title = models.CharField(max_length=255)
  5. 5. To customize your user table, there are 3 options...
  6. 6. Warranty We suggest that you carefully try out option #1 below, as it should work with a minimum of effort. For Django 1.5-style custom User model definitions, we recommend option #2 and option #3 for new projects only. ! This is is because custom User model definitions for option #2 and option #3 adds new User tables to the database that will not have the existing project data. Unless project-specific steps are taken to address matters, migration means ORM connections to related objects will be lost.
  7. 7. Option 1 - Link back You continue to use User (called preferably via django.contrib.auth.get user model()) and keep your related fields in a separate model (e.g. Profile). from django.conf import settings from django.db import models class UserProfile(models.Model): # If you do this you need to either have a post_save signal or # redirect to a profile_edit view on initial login. user = models.OneToOneField(settings.AUTH_USER_MODEL) favorite_ice_cream = models.CharField(max_length=30)
  8. 8. Option 2 AbstractUser Choose this option if you like Django’s User model fields the way they are, but need extra fields !from django.contrib.auth.models import AbstractUser from django.db import models from django.utils.translation import ugettext_lazy as _ ! class KarmaUser(AbstractUser): karma = models.PositiveIntegerField(_("karma"), default=0, blank=True) #Setting.py AUTH_USER_MODEL = "profile.KarmaUser"
  9. 9. Option 3 - Subclass AbstractBaseUser AbstractBaseUser is the bare-bones option with only 3 fields: password, last login, and is active. ! Let’s try it out with a custom User model for the Two Scoops project. Here are our requirements: We need an email address. We need to handle permissions per the traditional django.contrib.auth.models use of PermissionsMixin; providing standard behavior for the Django admin. We don’t need the first or last name of a user. We need to know their favorite ice cream topping. • • • •
  10. 10. Option 3 - cont.(1) 1. Start from model. 2. Model.UserManager create User -> override it to create TwoScoopsUser 3. We need TwoScoopsUser! class TwoScoopsUser(AbstractBaseUser, PermissionsMixin): email = models.EmailField( verbose_name='email address', max_length=255, unique=True, db_index=True, ) favorite_topping = models.CharField(max_length=255) is_active = models.BooleanField(default=True) is_admin = models.BooleanField(default=False) is_staff = models.BooleanField(default=False) ! ! objects = TwoScoopsUserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['favorite_topping']
  11. 11. Option 3 - cont.(2) Implement usage functions… def get_full_name(self): return self.email ! def get_short_name(self): return self.email ! def __unicode__(self): return self.email ! def has_perm(self, perm, obj=None): return True ! def has_module_perms(self, app_label): return True
  12. 12. Option 3 - cont. (3) Let’s write Model.UserManager to create TwoScoopsUser class TwoScoopsUserManager(BaseUserManager): def create_user(self, email, favorite_topping, password=None): """ Creates and saves a User with the given email, date of birth and password. """ ##Skip… user = self.model( email=TwoScoopsUserManager.normalize_email(email), favorite_topping=favorite_topping, ) ! user.set_password(password) user.save(using=self._db) return user
  13. 13. Option 3 - cont. (4) Let’s write Model.UserManager to create TwoScoopsUser ! def create_superuser(self, email, favorite_topping, password): """ Creates and saves a superuser with the given email, date of birth and password. """ user = self.create_user(email, password=password, favorite_topping=favorite_topping ) user.is_admin = True user.is_staff = True user.is_superuser = True user.save(using=self._db) return user
  14. 14. Option 3 - Let Admin show your data. Basically, override contrib.auth.admin … class TwoScoopsUserAdmin(UserAdmin): # The forms to add and change user instances form = TwoScoopsUserChangeForm add_form = TwoScoopsUserCreationForm ! ! # The fields to be used in displaying the User model. # These override the definitions on the base UserAdmin # that reference specific fields on auth.User. list_display = ("email", "is_staff", "favorite_topping") list_filter = ("is_staff", "is_superuser", "is_active", "groups") search_fields = ("email", "favorite_topping") ordering = ("email",) filter_horizontal = ("groups", "user_permissions",) fieldsets = ( (None, {"fields": ("email", "password")}), ("Personal info", {"fields": ("favorite_topping",)}), ("Permissions", {"fields": ("is_active", "is_staff", "is_superuser", "groups", "user_permissions")}), ("Important dates", {"fields": ("last_login",)}), ) add_fieldsets = ((None, { "classes": ("wide",), "fields": ("email", "favorite_topping", "password1", "password2")}), )
  15. 15. Option 3 - Let Admin show your data. (2) Implement your forms class TwoScoopsUserCreationForm(UserCreationForm): """A form for creating new users. Includes all the required fields, plus a repeated password.""" password1 = forms.CharField(label='Password', widget=forms.PasswordInput) password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput) #favorite_topping = forms.CharField( label='Faborate topping', widget=forms.TextInput) ! class Meta: model = TwoScoopsUser fields = ('email', 'favorite_topping') class TwoScoopsUserChangeForm(UserChangeForm): """A form for updating users. Includes all the fields on the user, but replaces the password field with admin's password hash display field. """ password = ReadOnlyPasswordHashField() ! class Meta: model = TwoScoopsUser fields = ["email", "password", "favorite_topping", "is_active", "is_staff", "is_superuser", "groups", "user_permissions", "last_login"]
  16. 16. Thanks
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×