Как я могу добавить inlines в ModelAdmin другого приложения без циклической зависимости?


Предположим, у меня есть две модели, в разных приложениях. Приложение два знает о приложении один, но не наоборот:

# one/models.py

from django.db import models

class One(models.Model):
    pass


# two/models.py

from django.db import models
from one.models import One

class Two(models.Model):
    one = models.ForeignKey(One)

У меня также есть One зарегистрированный в админ-сайте:

# one/admin.py

from django.contrib import admin
from .models import One

admin.site.register(One)

Как зарегистрировать Two в качестве встроенного на странице администратора One, не вводя циклическую зависимость между двумя приложениями?

3 3

3 ответа:

Вы можете сделать это довольно просто, при условии, что вы не возражаете против доступа к "приватному" атрибуту на ModelAdmin. (Атрибуты, начинающиеся с подчеркивания, считаются частными по соглашению.)

# two/admin.py
from django.contrib import admin
from one.models import One
from .models import Two

class TwoInline(admin.StackedInline):
    model = Two

admin.site._registry[One].inlines.append(TwoInline)

У меня была та же проблема, но я решил ее более мягким способом.

# one/admin.py

class OneAdmin(admin.ModelAdmin):
    model = One

admin.site.register(One, OneAdmin)

# two/admin.py

class TwoInline(admin.TabularInline):
    model = Two

import one.admin
class OneAdmin(one.admin.OneAdmin):
    inlines = [TwoInline]

admin.site.unregister(One)
admin.site.register(One, OneAdmin)

Как вы видите, я расширил исходный ModelAdmin из первого приложения и добавил inlines из второго приложения. Не забудьте отменить регистрацию модели из первого приложения, прежде чем регистрировать ее снова. Это безопасно и намного лучше, чем получить доступ к частному члену класса, как было предложено.

Я бы попробовал следующее:

# one/admin.py
from django.contrib import admin
from one.models import One
from two.models import Two

class TwoInline(admin.StackedInline):
    model = Two

class OneAdmin(admin.ModelAdmin):
    inlines = [TwoInline,]

admin.site.register(One, OneAdmin)

Вы можете прочитать больше вdocs .