Разделение на подклассы модели Django: Получите подкласс путем запросов суперкласса

Следующий код дан:

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')

но это решение, кажется, к сложному, и я думаю Вы, у парней есть лучшие решения.

8
задан Selcuk 10 July 2016 в 02:20
поделиться

2 ответа

Спасибо, мистер. Роземану за ответ. Я немного развил вашу идею. Вот что я придумал:

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.

1
ответ дан 5 December 2019 в 20:13
поделиться

Единственный способ сделать это — явно сохранить на базовой модели, какого она типа. Поэтому испустите поле 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

и так далее.

2
ответ дан 5 December 2019 в 20:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: