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.