Следующий код дан:
class BaseMedium(models.Model):
title = models.CharField(max_length=40)
slug = models.SlugField()
class A(BaseMedium):
url = models.URLField()
class B(BaseMedium):
email = models.EmailField()
Я теперь хочу запросить каждый BaseMedium.
b = BaseMedium.objects.all()
Как я печатаю каждую информацию включая поля подкласса, не зная, каков тип подкласса?
b[0].a
распечатал бы информацию если b[0]
на самом деле связан с A
экземпляр, но если это связано с B
это распечатало бы DoesNotExist
Исключение.
Это имеет смысл, но я хотел бы иметь общую переменную или метод, который возвращает связанный объект.
Возможно, мое расположение Базы данных не является действительно большим запросить тот путь раз так, я радовался бы, рекомендуете ли Вы лучшее расположение.
Я думал об использовании a GenericForeignKey
class Generic(models.Model):
basemedium = models.ForeignKey('BaseMedium')
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
object = generic.GenericForeignKey('content_type', 'object_id')
но это решение, кажется, к сложному, и я думаю Вы, у парней есть лучшие решения.
Спасибо, мистер. Роземану за ответ. Я немного развил вашу идею. Вот что я придумал:
def related_object(self, default_pointer_name='_ptr'):
models = [A,B] #models
object = None
argument = '%s%s' %(self.__class__.__name__.lower(), default_pointer_name)
query = { argument : self}
for model in models:
try:
object = model.objects.get(**query)
except model.DoesNotExist:
pass
else:
return object
if object == None:
raise RelatedObjectException
return object
Это метод, используемый BaseMedium.
Единственный способ сделать это — явно сохранить на базовой модели, какого она типа. Поэтому испустите поле derived_type
(или что-то еще) в BaseMedium и установите его на сохранение. Тогда вы можете иметь метод get_derived_type
:
def get_derived_type(self):
if self.derived_type == 'A':
return self.a
elif self.derived_type == 'B':
return self.b
и так далее.