python - 使用 OneToOneField 扩展 Django Admin UserCreationForm

标签 python django python-2.7 django-forms django-admin

我正在尝试扩展 django admin UserCreationForm 以包含与 OneToOneField 相关的另一个表中的字段。

这是我的相关表格:

class Profile(models.Model):
    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE
    )
    supervisor = models.ForeignKey(
        User,
        related_name='supervisor',
        on_delete=models.DO_NOTHING,
        blank = True,
        null = True
    )

还有我的管理表单:

from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.contrib.auth.models import User
from django import forms

class EmailRequiredMixin(object):
    def __init__(self, *args, **kwargs):
        super(EmailRequiredMixin, self).__init__(*args, **kwargs)
        # make user email field required
        self.fields['email'].required = True


class MyUserCreationForm(EmailRequiredMixin, UserCreationForm):
    supervisor = forms.Select()

    class Meta:
        model = User
        fields = ['username',]

    def save(self, commit=True):
        if not commit:
            raise NotImplementedError("Can't create User and UserProfile without database save")
        user = super(MyUserCreationForm, self).save(commit=True)
        profile = Profile(user=user, supervisor=self.cleaned_data['supervisor'])
        profile.save()
        return user, profile

class EmailRequiredUserAdmin(UserAdmin):
    inlines = [ProfileInline, ]
    list_display = ['username', 'email', 'first_name', 'last_name', 'is_staff', 'get_supervisor', 'get_is_supervisor', 'get_is_project_manager']
    form = MyUserChangeForm
    add_form = MyUserCreationForm
    add_fieldsets = ((None, {'fields': ('username', 'email',
                                        'password1', 'password2'), 'classes': ('wide',)}),)

    def get_supervisor(self, instance):
        return instance.profile.supervisor
    get_supervisor.short_description = 'Supervisor'

    def get_is_supervisor(self, instance):
        return instance.profile.is_supervisor()
    get_is_supervisor.short_description = 'Is Supervisor'

    def get_is_project_manager(self, instance):
        return instance.profile.is_project_manager()
    get_is_project_manager.short_description = 'Is Project Manager'

    def get_inline_instances(self, request, obj=None):
        if not obj:
            return list()
        return super(EmailRequiredUserAdmin, self).get_inline_instances(request, obj)

admin.site.unregister(User)
admin.site.register(User, EmailRequiredUserAdmin)

在 django-admin 中,它只显示正常的创建表单,但我需要包括主管。我知道现阶段我还没有包含主管的查询集,但我认为这解释了我想要实现的目标以及我已经尝试过的内容。

非常感谢帮助。

最佳答案

您还需要将主管字段添加到您的管理 add_fieldsets 中。

class MyTestForm(UserCreationForm):
    supervisor = forms.ModelChoiceField(queryset=User.objects)

    def save(self, commit=True):
        supervisor = self.cleaned_data['supervisor']
        # Save user first 
        user = super(MyTestForm, self).save(commit=True)
        profile = Profile.objects.create(user=user)
        profile.supervisor = supervisor
        profile.save()
        return user


class MyUserAdmin(UserAdmin):
    add_form = MyTestForm
    form = UserChangeForm
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('supervisor', 'username', 'password1', 'password2')
        }),
    )

我测试了这个解决方案,主管在创建步骤中显示为下拉列表。 希望对您有所帮助。

关于python - 使用 OneToOneField 扩展 Django Admin UserCreationForm,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48766059/

相关文章:

python - 用乏味的 __init__ 模拟一个类

python - .lower()

python - 如何在 2D 平面上可视化 4D 数据?

python - Django - 表单 - (?P<pk>\d+)/$ 表示什么?

python - 如何解决python 'utf-8'错误?

python - html 模板中的 Django for 循环不显示

python - Django 反向错误 : NoReverseMatch

testing - 如何测试程序是否退出

python - 使用 matplotlib.pyplot 从 csv 中绘制数据

python - 导入错误: No module named 'selenium' in Sublime text plugin