Как получить имя абстрактного класса из дочернего класса

У меня есть несколько моделей, как показано ниже,

class FooBarAbstract(models.Model):
    foobar = models.IntegerField()

    class Meta:
        abstract = True


class Foo(FooBarAbstract):
    foo = models.IntegerField()


class Bar(FooBarAbstract):
    bar = models.IntegerField()



Как я могу получить имя абстрактного класса (FooBarAbstract), используя дочерние классы (Foo или Bar) или их объекты?

Попробовать .mro ()? (Порядок разрешения метода)

Vineeth Sai 10.09.2018 09:34

@VineethSai Частично выполняет свою работу, возвращая tuple. Но мне нужна строка

JPG 10.09.2018 09:38

@JPG Вы можете получить имя через атрибут .__name__ элементов кортежа. Но, может быть, можно уточнить, для чего это нужно? Возможно, есть лучший подход.

schwobaseggl 10.09.2018 09:40

Что делать, если существует несколько (абстрактных) моделей, от которых модель наследуется? Считаем ли мы косвенное наследование (модель, унаследованная моделью, унаследованной Bar)?

Willem Van Onsem 10.09.2018 09:52

@WillemVanOnsem Модель наследует только один абстрактный класс. Но может быть возможность для Множественное наследование

JPG 10.09.2018 10:15

Вполне возможно позволить модели наследовать от нескольких абстрактных моделей (через косвенное наследование или множественное наследование). Поэтому я считаю целесообразным уточнить, что должно происходить в этих случаях.

Willem Van Onsem 10.09.2018 10:19

Думаю, мне стоит обдумать эти вещи, но сейчас я особо не копаю :)

JPG 10.09.2018 11:03
1
7
679
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Попробуйте что-то вроде этого. Это пример, и вы можете изменить индекс в соответствии с иерархией Django.

class Foo():
    pass

class Bar(Foo):
    pass

class Eggs(Foo):
    pass

Теперь о классе "Яйца"

Eggs.mro()[-2].__name__ # change your index accordingly to your class inheritance structure.

Returns Foo

для информации:

Абстрактный класс Django предназначен только для того, чтобы убедиться, что они не создают дополнительную таблицу в базе данных.

Ответ принят как подходящий

Вы можете получить имена базовых классов класса из атрибута __bases__ класса.

Предполагая, что ваши производные классы всегда наследуются только от одного класса, вы можете использовать следующее, чтобы получить имя базового класса:

class Foo(FooBarAbstract):
    def __init__(self):
        print(self.__class__.__bases__[0].__name__)

чтобы Foo() выводил: FooBarAbstract

Обратите внимание, что метод mro и атрибут __mro__ менее подходят для вашей цели, потому что они содержат не только родительский класс, но также текущий класс и родительский класс родительского класса, поэтому вам придется пропустить их, прежде чем вы сможете получить родительский класс.

Используя python __bases__, он вернет кортеж имен базовых классов:

class Foo():
    pass

class Bar(Foo):
    pass

bb = Bar
bb.__bases__[0].__name__
# 'Foo'

Но я не знаю, есть ли в django дополнительный способ справиться с этим.

Другие вопросы по теме