Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Red User, Blue User, MyUser, auth.User

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Red User, Blue User, MyUser, auth.User

An exploration of one of the banner features of Django 1.5 -- Custom User models. Includes worked examples, a discussion of design decisions that must be made, and a look at the internal architecture that makes it all possible.

Avatar for Russell Keith-Magee

Russell Keith-Magee

September 04, 2013
Tweet

More Decks by Russell Keith-Magee

Other Decks in Technology

Transcript

  1. Other tips • Don’t assume a single letter is an

    initial • Be wary of name-part algorithms • Spaces, Apostrophes and Hyphens are all legal characters in names • Don’t require a “family name” • “Previous name”, not “Maiden name” • Honorifics even more complex
  2. 1. Define user model • 2 possible abstract base classes:

    • AbstractBaseUser • AbstractUser • Maybe with PermissionsMixin • Define USERNAME_FIELD • Define REQUIRED_FIELDS • Define get_full_name() and get_short_name()
  3. 2. Define your Manager • Need to describe: • How

    to create users • How to create superusers
  4. 4. Register with admin • Only need to do this

    if you’re using admin • Subclass contrib.admin.UserAdmin • admin.site.register() • Don’t need to unregister default User
  5. Reverse lookup naming class Department(Model): ... class User(AbstractUser): full_name =

    CharField() department = ForeignKey(Department) department = Department.objects.get(...) print department.user_set.all()
  6. Reverse lookup naming class Department(Model): ... class MyUser(AbstractUser): full_name =

    CharField() department = ForeignKey(Department) department = Department.objects.get(...) print department.myuser_set.all()
  7. Reverse lookup naming class Department(Model): ... class MyUser(AbstractUser): full_name =

    CharField() department = ForeignKey(Department, related_name=‘user_set’) department = Department.objects.get(...) print department.user_set.all()
  8. Reverse lookup naming class Department(Model): ... class MyUser(AbstractUser): full_name =

    CharField() department = ForeignKey(Department) department = Department.objects.get(...) attr = “%s_set” % user._meta.object_name print getattr(department,attr).all()
  9. Email-based login • Define a user model with • email

    = EmailField(max_length=254) • USERNAME_FIELD = ‘email’ • Define forms, admin, etc • Set AUTH_USER_MODEL
  10. Kerberos Single Sign-on • “username” is your Kereros token: username@domain

    • Define an authentication backend that converts credentials into users
  11. Authentication Backends • On login, you provide a credentials dict

    • Usually, Username and Password • Can be anything • Authentication backend turns credentials into a validated user • Can have multiple authentication backends.
  12. Option 2: class User(AbstractUser): ... class UserProfile(Model): full_name = CharField()

    user = OneToOneField(User) birth_date = DateField() avatar = FileField()
  13. Option 2: class User(AbstractUser): ... class IdentityProfile(Model): user = OneToOneField(User)

    full_name = CharField() birth_date = DateField() class DisplayProfile(Model): user = OneToOneField(User) avatar = FileField()
  14. Option 3: Hybrid class User(AbstractUser): full_name = CharField() class UserProfile(Model):

    user = OneToOneField(User) birth_date = DateField() avatar = FileField()
  15. How it works • No internal references to auth.User •

    auth.User has a Meta property: swappable = ‘AUTH_USER_MODEL’ • Defines the name of a setting • Inspected at runtime for the “real” class • generates Meta.swapped • The rest is just validation
  16. ForeignKeys + M2M • No new features in ForeignKey or

    M2M • ForeignKey(‘auth.User’) has always worked • Now, we’re just using a setting • Validation that ForeignKey doesn’t point at a “swapped” model.