A interface de administração do Django não usa o __unicode __ () da subclasse

(Django 1.x, Python 2.6.x)

Eu tenho modelos para a melodia de:

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)

Não instalei nenhum Animal, porque essa deveria ser uma classe virtual. Instanciei Gatos e Cães, mas na Página de Administração do AnimalHome, minhas escolhas para Animais são exibidas como "Objeto animal" (o padrão __unicode __ (), eu acho) em oposição ao __unicode__ que defini para as duas subclasses. Socorro.

A questão da classe base abstrata é um arenque vermelho para esta questão, eu acho. Mesmo que Animal não fosse abstrato, ainda tenho o problema de que, por algum motivo, como a ForeignKey é definida em Animal e não em uma de suas subclasses, o método da superclasse está sendo chamado em vez da subclasse. Na programação OO, quando você chama object.method (), você deve obter a implementação da subclasse mais baixa e precisa fazer um trabalho extra para obter a implementação de qualquer superclasse. Então, por que ter __unicode__ definido nas subclasses não é suficiente para --- na verdade, o problema pode ser que __unicode__ não está sendo chamado de todo porque a introspecção na classe Animal revela que não está definido. Então, se eu definir __unicode__ para Animal e chamar as subclasses '__unicode__, eu poderia obter o efeito desejado.

Ok, acho que entendo os problemas do ORM. Ambas as respostas me ajudaram a entender isso, obrigado. Ao experimentar isso, descobri que, quando o Django salva um modelo de subclasse, ele faz duas coisas: (1) cria uma linha para o objeto subclasse na tabela da superclasse e (2) torna a PK na tabela da subclasse idêntica a a PK atribuída na tabela da superclasse. Essa PK na tabela da subclasse é denominada superclass_ptr. Com base nisso, inventei o seguinte. Eu gostaria de receber feedback.

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!"

Parece que Lawrence é o mais pontual nesta questão. Cat and Dog terão conjuntos PK separados (e qualquer subclasse de Animal terá um PK idêntico ao registro de sua superclasse), mas infelizmente o Django não realiza nenhum trabalho nos bastidores: "Eu sou um animal. Eu sei Os animais têm subclasses Cão e Gato. Especificamente, sou o número 3 do animal e, além disso, acabei de verificar e existe também o número 3 do gato. Isso significa que na verdade sou o número 3 do gato ". Mesmo que isso pareça inteiramente possível e muito razoável (já que um gato não fará nada que um animal não possa fazer sozinho) usando a introspecção de Python. Obrigado a todos.

questionAnswers(6)

yourAnswerToTheQuestion