简体   繁体   English

Django Admin内嵌OneToOne字段

[英]Django Admin Inlines With OneToOne Field

Here in my model, you can see that I have a SpecializedProfile with a OneToOne relationship with a UserProfile, with a OneToOne relationship with the django user model. 在我的模型中,您可以看到我的SpecializedProfile与UserProfile具有OneToOne关系,与django用户模型具有OneToOne关系。

I want to create an admin for the SpecializedProfile containing inlines for the UserProfile and the django User model, so that I can create a SpecializedProfile all at once, without needing to go to the UserProfile page and the User page. 我想为SpecializedProfile创建一个包含UserProfile和django User模型的内联的管理员,以便我可以一次全部创建SpecializedProfile,而无需转到UserProfile页面和User页面。

Here is my model: 这是我的模型:

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...

and here is my attempt at creating the admin: 这是我尝试创建管理员的尝试:

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)

The admin isn't working, and I am getting this error: 管理员无法正常工作,并且出现此错误:

<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'.

It seems like django wants the inlines to be on the models where the OneToOne fields are defined, and won't accept reverse relationships. django似乎希望将内联线放在定义OneToOne字段的模型上,并且不接受反向关系。 I'd rather not have to go restructuring my models to make this work... is there anything I can do to make the inlines work with my model as-is? 我宁可不必重组模型来完成这项工作...我可以做些什么来使内联按原样使用我的模型吗?

I fixed that error by making reverse side inline, not from Profile to User but from overridden User to Profile: 我通过使背面内联而不是从个人资料到用户而是从覆盖的用户到个人资料来内联来解决该错误:

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)

Then I also tweaked Profile admin (removed Add action and changed some field links to custom ones). 然后,我还调整了Profile admin(删除了Add操作,并将某些字段链接更改为自定义链接)。

There's a django module on github that will do this for you, without you having to reverse the relationships: django_reverse_admin . github上有一个django模块,可以为您完成此操作,而无需撤销关系: django_reverse_admin

Once installed, your admin would look like: 安装后,您的管理员将如下所示:

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

Unfortunately, I don't think it can do nested inlines (Django can't either), so that would only solve part of your problem. 不幸的是,我不认为它可以嵌套内联(Django也不能),因此只能解决部分问题。 I know you didn't want to change your database structure, but SpecializedProfile really seems more like a subclass of UserProfile. 我知道您不想更改数据库结构,但是SpecializedProfile实际上似乎更像是UserProfile的子类。 If you rewrote your model like so: 如果您像这样重写模型:

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

Then you could have the admin like this: 然后,您可以像这样的管理员:

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

This way, you can view everything inline for both UserProfile and SpecializedProfile. 这样,您可以内联查看UserProfile和SpecializedProfile的所有内容。

There is no way nested inlines (inline inside inline) in django.contrib.admin . django.contrib.admin没有nested inlines (inline inside inline)的方法。

maybe this help you: 也许这可以帮助您:

class UserInline(admin.TabularInline):
    model = User

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

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

You'd also need to provide your own templates that would have nested iteration over both the top level inline and it's child inline. 您还需要提供自己的模板,这些模板将在顶级内联和子内联上嵌套嵌套迭代。

Also take a look at this , maybe help you. 也看看这个 ,也许对你有帮助。

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

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