Home > Software engineering >  Admin site for custom user model and extended user model
Admin site for custom user model and extended user model

Time:08-24

My Django app needs custom user model and some additional fields so I have defined them as below:

Custom User Model and Manager (defined in an app called users):

class CustomUserManager(BaseUserManager):

    use_in_migrations = True

    def _create_user(self, email, password, **extra_fields):
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        return self._create_user(email, password, **extra_fields)


class CustomUser(AbstractUser):
    username = None
    email = models.EmailField(unique=True)

    objects = CustomUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.email

Extra model field (defined in an app called api):

class Customer(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    created = models.DateField(auto_now_add=True)

The Admin Site (defined in users app):

class CustomerInline(admin.StackedInline):
    model = Customer
    readonly_fields = ('created',)


@admin.register(CustomUser)
class CustomUserAdmin(UserAdmin):

    inlines = (CustomerInline,)

    list_display = ('email', 'is_active', 'is_staff', 'is_superuser')

    list_filter = ('email', 'is_active', 'is_staff', 'is_superuser')

    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Personal info', {'fields': ('first_name', 'last_name')}),
        (
            ('Permissions'),
            {
                'fields': (
                    'is_active',
                    'is_staff',
                    'is_superuser',
                    'groups',
                    'user_permissions',
                )
            },
        ),
    )

    add_fieldsets = (
        (
            None,
            {
                'classes': ('wide',),
                'fields': (
                    'email',
                    'password1',
                    'password2',
                    'is_active',
                    'is_staff',
                    'is_superuser',
                ),
            },
        ),
    )

    search_fields = ('email',)

    ordering = ('email',)

Admin site works almost fine except that nothing is shown for created field while it must show the date of creation of the user.

I know that Django has date_joined and I may use that instead. The issue is why my inline is not working properly.

enter image description here

CodePudding user response:

Your Customer is not created together with the CustomUser automatically. What you see in the admin is just form for adding new Customer with all fields readonly. Once you save it I assume the Customer gets created as well. You should handle it though in the scenarios where the goal is to have CustomUser always have Customer attached. You can either put it directly to the place CustomUsers are created, e.g. admin, registration, etc. Or use signal on CustomUser creation that creates Customer as well.

  • Related