Полиморфное поведение в админке Джанго - PullRequest
2 голосов
/ 26 апреля 2011

Проблема

Предположим, у меня есть три класса A, B и C, где B является подклассом A, а C является подклассом B:

A <- B <- C

Когда я открываю админ и перечисляю все буквы "A", я вижу все буквы "A", "B" и "C". Но когда я перейду по одной из этих ссылок, чтобы увидеть детали и отредактировать конкретный B, я увижу только поля B, даже если этот экземпляр фактически является экземпляром C. То, что я хотел бы видеть, - это объект, который будет показан мне в соответствии с его наиболее конкретным типом.

Что я пытаюсь

Я использую InheritanceManager , чтобы получить экземпляры, приведенные к нужному типу при работе на более абстрактном уровне. Это работает почти хорошо (не может обрабатывать более одного уровня наследования). Однако даже для одного уровня наследования я не могу отразить полиморфное поведение администратора, поскольку очевидно, что администратор не знает о методе select_subclasses() менеджера.

Есть какие-нибудь идеи о том, как я могу использовать такое полиморфное поведение для администратора?

Конкретный пример

models.py:

from django.db import models
from model_utils.managers import InheritanceManager

class A(models.Model):
    a_field = models.CharField(max_length=200)
    objects = InheritanceManager()

class B(A):
    b_field = models.CharField(max_length=200)

class C(B):
    c_field = models.CharField(max_length=200)

admin.py

from myapp.models import A, B, C
from django.contrib import admin

admin.site.register(A)
admin.site.register(B)
admin.site.register(C)

Обновление

Добавление ссылки на две темы 2010 года с некоторыми соображениями о том, как этого добиться с помощью django-polymorphic:

1 Ответ

2 голосов
/ 30 апреля 2011

Этот ответ неполный, поскольку я не могу воспроизвести ваш первый выпуск. Когда я перечисляю объекты родительской модели, я вижу их все. (Или, может быть, есть какое-то недопонимание.)


Проблема с неполными полями может быть частично решена с помощью встроенного администратора. Поскольку подкласс - это просто модель с неявным отношением OneToOneField к родительской модели, вы можете определить встроенную строку для «C», а затем включить ее в атрибут inlines в администраторе B.

Проблемы:

  • Пользователь не сможет создать объект класса "C" через встроенный админ B; это может быть сделано только через администратора С. Это только просмотр.
  • Он не будет работать с несколькими уровнями наследования: вы можете включить B в администратор A в качестве встроенного, но я не знаю простого способа включить C в качестве встроенного для встроенного в B.

Другой способ - изменить шаблон администратора A, поместив там ссылку на реальный экземпляр (будь то B или C). Но я полагаю, вы уже подумали об этом.


Относительно последнего вопроса: если вы хотите изменить набор запросов администратора какой-либо модели, это можно сделать с помощью метода queryset() ModelAdmin (см. Пример в этот вопрос ). Вы можете переопределить этот метод на администраторе вашей модели и разместить там логику select_subclasses(). Но я не пробовал, поэтому не могу сказать, как поведет себя ModelAdmin, если вы сделаете это. Возможно, вам придется переопределить еще несколько методов.


PS. В настоящее время я использую django-polymorphic, работая над аналогичным проектом с конкретным наследованием. Он также не предоставляет каких-либо средств для управления полиморфными моделями через администратора, поэтому я решил не полагаться на администраторов Django для этого, а просто создать простой пользовательский интерфейс для сотрудников сайта, думаю, это не займет много времени.

...