Merging "add" form in Django Admin from 2 or more Models (connected with one-to-one relationship)

Assuming you have Profile with extra field phone_number. Like this

class Profile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    phone_number = models.CharField(max_length=24)

You can follow following steps to add extra fields in UserCreationForm in Admin.

1. Create custom UserCreationForm

Inherit from UserCreationForm and Add extra fields and functionality.

from django import forms
from django.contrib.auth.forms import UserCreationForm
from account.models import Profile

class UserWithProfileCreationForm(UserCreationForm):
    phone_number = forms.CharField(max_length=32)

    def save(self, commit=True):
        instance = super().save(commit=True)
        profile = Profile(user=instance, phone_number=self.cleaned_data['phone_number'])
        profile.save()
        return instance

2. Unregister (already registered) User model and register again with custom form and fields

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User

# unregister first
admin.site.unregister(User)


@admin.register(User)
class UserWithProfileAdmin(UserAdmin):
    add_form = UserWithProfileCreationForm
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            # add any custom fields here
            'fields': ('username', 'password1', 'password2', 'phone_number'),
        }),
    )

There are two ways to do this. First, you can create a custom User model from AbstractBase

# models.py
class MyUser(AbstractBaseUser):
    profile = models.OneToOneField(UserProfile)

And then update your admin view.

#admin.py

from django.contrib.auth.admin import UserAdmin

class UserProfileInline(admin.TabularInline):
    model = UserProfile

class MyUserAdmin(UserAdmin):
    inlines = [
        UserProfileInline,
    ]

admin.site.register(MyUser, MyUserAdmin)

Second, you can simply add the OneToOneField(User) in your UserProfile model, and follow the similar method to update the admin view.

Tags:

Python

Django