Интерфейс администратора Django не использует подкласс __unicode __ ()

(Django 1.x, Python 2.6.x)

У меня есть модели на мотив:

class Animal(models.Model):
  pass

class Cat(Animal):
  def __unicode__(self):
    return "This is a cat"

class Dog(Animal):
  def __unicode__(self):
    return "This is a dog"

class AnimalHome(models.Model):
  animal = models.ForeignKey(Animal)

Я не создавал никаких животных, потому что это должен быть виртуальный класс. Я создал экземпляры Cats и Dogs, но на странице администратора для AnimalHome мой выбор для Animals отображается как «Объект Animal» (я полагаю, __unicode __ () по умолчанию), а не __unicode__, который я определил для двух подклассов. Помогите.

Я думаю, что проблема абстрактного базового класса - красная сельдь по отношению к этому вопросу. Даже если Animal не должен был быть абстрактным, у меня все еще есть проблема, заключающаяся в том, что, по какой-то причине, поскольку ForeignKey определен в Animal, а не в одном из его подклассов, вместо подкласса вызывается метод суперкласса. В ОО-программировании, когда вы вызываете object.method (), вы должны получить реализацию самого низкого подкласса, и вам нужно проделать дополнительную работу, чтобы получить реализацию любого суперкласса. Так почему же для определения __unicode__ на подклассах недостаточно - на самом деле проблема может заключаться в том, что __unicode__ вообще не вызывается, потому что самоанализ класса Animal показывает, что он не определен. Так что, может быть, если я определю __unicode__ для Animal и вызову его для подклассов __unicode__, я получу желаемый эффект.

Хорошо, я думаю, что понимаю проблемы ORM. Оба эти ответа помогли мне понять это, спасибо. Экспериментируя с этим, я обнаружил, что когда Django сохраняет подклассовую модель, он делает две вещи: (1) создает строку для подклассового объекта в таблице суперкласса и (2) делает PK в таблице подкласса идентичным ПК назначен в таблице суперкласса. Этот PK в таблице подклассов называется superclass_ptr. На основании этого я придумал следующее. Буду признателен за отзыв.

Class Animal(models.Model)
  def __unicode__(self):
    if Dog.objects.filter(pk=self.pk).count() > 0:
      return unicode(Dog.objects.get(pk=self.pk))
    elif Cat.objects.filter(pk=self.pk).count() > 0:
      return unicode(Cat.objects.get(pk=self.pk))
    else:
      return "An Animal!"

Похоже, что Лоуренс в наибольшей степени относится к этому вопросу. У Cat и Dog будут непересекающиеся наборы ПК (и у любого подкласса Animal будет PK, идентичный записи его суперкласса), но, к сожалению, Django не выполняет никакой закулисной работы: «Я - Животное. Я знаю У животных есть подклассы Собака и Кошка. В частности, я - Животное № 3, и, кроме того, я только что проверил, и есть также Кошка № 3. Это означает, что я на самом деле Кошка № 3 ". Даже при том, что это кажется вполне возможным и очень разумным (поскольку Кошка не будет делать ничего, что Животное не может сделать сама), используя интроспекцию Python. Спасибо вам всем.

Ответы на вопрос(6)

Ваш ответ на вопрос