Code


Version 1 (modified by Adam Endicott <leftwing17@…>, 9 years ago) (diff)

--

This is a work in progress, I just discovered this a couple of hours ago.

There's an undocumented (as of this writing) way to do model inheritance. The magic involves defining add_fields , ignore_fields , and replaces_module . Here's an example of extending auth.User:

from django.core import meta
from django.models import auth

class User(auth.User):
    add_fields = (
         meta.ForeignKey(Company),
         meta.PhoneNumberField('phone', blank=True),
         meta.SmallIntegerField('extension', blank=True, null=True),
         meta.CharField('position', maxlength=255, blank=True),
        )
    replaces_module = 'auth.users'

    admin = meta.Admin(
        fields = (
            (None, {'fields': ('username', 'password_md5')}),
            ('Personal info', {'fields': ('first_name', 'last_name', 'email')}),
            ('Extra info', {'fields': ('company_id', 'phone', 'extension', 'position')}),
            ('Permissions', {'fields': ('is_staff', 'is_active', 'is_superuser', 'user_permissions')}),
            ('Important dates', {'fields': ('last_login', 'date_joined')}),
            ('Groups', {'fields': ('groups',)}),
        ),
        list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff'),
        list_filter = ('is_staff', 'is_superuser'),
        search_fields = ('username', 'first_name', 'last_name', 'email'),
    )

This model will have everything in auth.User, as well as all the fields in add_fields. Since I defined replaces_module as auth.users, it actually replaces the auth.User model. If replaces_module was not defined, it would just be a separate users model, though it would still have all the same fields.

I haven't tried ignore_fields yet, but I presume that it will cause specified fields to be removed from the model. It looks like it takes a list of field names.

Notice also that I've redefined admin above to include the extra fields. Be sure to do that if you want them to show up in the admin interface.

Gotchas

Replacing auth.User in this way breaks createsuperuser. You'll have to add an inital superuser to the database manually.

If your other model classes have foreign, or many to many relationships with User, make sure its to your redefined User class, not auth.User, otherwise the user objects will not have the expected get_otherthing() methods.