Объединение формы «добавить» в Django Admin из 2 или более моделей (связанных отношением «один к одному»)

#python #django

#python #django

Вопрос:

У меня есть Django по умолчанию UserCreationForm для добавления нового пользователя через приложение администратора. Я хочу добавить новые поля из другой пользовательской модели UserProfile . UserProfile Имеет взаимно однозначную связь с User моделью Django. Дополнительные поля, которые UserProfile имеет модель phone number , company name и т.д.

Есть ли способ, с помощью которого я могу объединить UserProfile форму с User формой Django по умолчанию при создании нового пользователя из панели администратора?

Я просмотрел документацию Django здесь по встроенным формам, но, похоже, они требуют отношения внешнего ключа.

Django 2.1

Комментарии:

1. Это может потребовать некоторой работы, но вы можете расширить AbstractUser . Если вы решите пойти по этому пути, вам также потребуется создать пользовательскую UserCreationForm. См.: Пользовательская модель пользователя. Хотя, вероятно, есть более простые способы выполнить то, что вы пытаетесь сделать.

2. Спасибо, я посмотрю на пользовательскую модель пользователя.

Ответ №1:

Предполагая, что у вас есть Profile дополнительное поле phone_number . Вот так

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

Вы можете выполнить следующие шаги, чтобы добавить дополнительные поля в UserCreationForm in Admin.

1. Создайте пользовательский UserCreationForm

Наследование UserCreationForm и добавление дополнительных полей и функций.

 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. Отмените регистрацию (уже зарегистрированной) User модели и зарегистрируйтесь снова с пользовательской формой и полями

 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'),
        }),
    )
  

Ответ №2:

Это можно сделать двумя способами. Во-первых, вы можете создать пользовательскую User модель из AbstractBase

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

  

А затем обновите свой вид администратора.

 #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)
  

Во-вторых, вы можете просто добавить OneToOneField(User) в свою UserProfile модель и следовать аналогичному методу для обновления представления администратора.