繁体   English   中英

Django Admin内嵌OneToOne字段

[英]Django Admin Inlines With OneToOne Field

在我的模型中,您可以看到我的SpecializedProfile与UserProfile具有OneToOne关系,与django用户模型具有OneToOne关系。

我想为SpecializedProfile创建一个包含UserProfile和django User模型的内联的管理员,以便我可以一次全部创建SpecializedProfile,而无需转到UserProfile页面和User页面。

这是我的模型:

class UserProfile(models.Model):
    user_auth = models.OneToOneField(User, related_name="profile", primary_key=True)
    # more fields...


class SpecializedProfile(models.Model):
    profile = models.OneToOneField(UserProfile, related_name="specialized_profile", primary_key=True)
    # More fields...

这是我尝试创建管理员的尝试:

class UserInline(admin.TabularInline):
    model = User
    fk_name = 'profile__specialized_profile'

class ProfileInline(admin.TabularInline):
    model = UserProfile
    fk_name = 'specialized_profile'

class SpecializedProfileAdmin(admin.ModelAdmin):
    model = SpecializedProfile
    inlines = [
        UserInline, ProfileInline
    ]

admin.site.register(SpecializedProfile, SpecializedProfileAdmin)

管理员无法正常工作,并且出现此错误:

<class 'profiles.admin.ProfileInline'>: (admin.E202) 'profiles.UserProfile' has no field named 'trainer'.
<class 'profiles.admin.UserInline'>: (admin.E202) 'auth.User' has no ForeignKey to 'profiles.SpecializedProfile'.

django似乎希望将内联线放在定义OneToOne字段的模型上,并且不接受反向关系。 我宁可不必重组模型来完成这项工作...我可以做些什么来使内联按原样使用我的模型吗?

我通过使背面内联而不是从个人资料到用户而是从覆盖的用户到个人资料来内联来解决该错误:

class ProfileInline(admin.StackedInline):
    model = Profile

class IspUserAdmin(UserAdmin):
    list_display = ('username', 'first_name', 'last_name', 'email', 'is_staff', 'is_superuser', 'is_active')
    list_filter = ('date_joined', 'last_login', 'is_staff', 'is_superuser', 'is_active',)
    inlines = (ProfileInline,)

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

然后,我还调整了Profile admin(删除了Add操作,并将某些字段链接更改为自定义链接)。

github上有一个django模块,可以为您完成此操作,而无需撤销关系: django_reverse_admin

安装后,您的管理员将如下所示:

# admin.py
from django_reverse_admin import ReverseModelAdmin


class SpecializedProfileAdmin(ReverseModelAdmin):
    model = SpecializedProfile
    inline_reverse = ['profile']
    inline_type = 'tabular'  # could also be 'stacked'

admin.site.register(SpecializedProfile, SpecializedProfileAdmin)

不幸的是,我不认为它可以嵌套内联(Django也不能),因此只能解决部分问题。 我知道您不想更改数据库结构,但是SpecializedProfile实际上似乎更像是UserProfile的子类。 如果您像这样重写模型:

class SpecializedProfile(UserProfile):
    # More fields...

然后,您可以像这样的管理员:

# admin.py
from django_reverse_admin import ReverseModelAdmin

class UserProfileAdmin(ReverseModelAdmin):
    model = UserProfile
    inline_reverse = ['user_auth']
    inline_type = 'tabular'


class SpecializedProfileAdmin(ReverseModelAdmin):
    model = SpecializedProfile
    inline_reverse = ['user_auth']
    inline_type = 'tabular'

admin.site.register(SpecializedProfile, SpecializedProfileAdmin) 
admin.site.register(UserProfile, UserProfileAdmin)

这样,您可以内联查看UserProfile和SpecializedProfile的所有内容。

django.contrib.admin没有nested inlines (inline inside inline)的方法。

也许这可以帮助您:

class UserInline(admin.TabularInline):
    model = User

class ProfileInline(admin.TabularInline):
    model = UserProfile
    inlines = [UserInline]

class SpecializedProfileAdmin(admin.ModelAdmin):
    model = SpecializedProfile
    inlines = [ProfileInline]

您还需要提供自己的模板,这些模板将在顶级内联和子内联上嵌套嵌套迭代。

也看看这个 ,也许对你有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM