Модель Джанго - Стоимость наследования - PullRequest
2 голосов
/ 23 марта 2012

У нас есть проект django, и мы обнаружили, что некоторые модели становятся огромными.

class BigModel(models.Model):
    """
    Large set of fields
    """
    field1 = models.IntegerField()
    field2 = models.IntegerField()
    field3 = models.IntegerField()
    ...
    fieldN = models.IntegerField()
    """
    Large set of methods
    """
    def method1(self): pass
    def method2(self): pass
    def method3(self): pass
    ...
    def methodN(self): pass

Я хочу разделить класс BigModel на более мелкие классы со списком методов. Но во всем проекте у нас есть ссылки на класс BigModel.

Так что моя идея состоит в том, чтобы сделать это маленькими шагами:

  1. Разделите BigModel класс на BigFields и BigMethods. унаследовать BigMethods из BigFields. Наследовать BigModel от BigMethods.
  2. Путем создания прокси-моделей и замены ссылок на BigModel на них в коде - уменьшите размер класса BigMethods.

Итак, в момент рефакторинга наш код будет выглядеть так:

class BigFields(models.Model):
    class Meta:
        abstract = True
    """
    Large set of fields
    """
    field1 = models.IntegerField()
    field2 = models.IntegerField()
    field3 = models.IntegerField()
    ...
    fieldN = models.IntegerField()

class BigMethods(BigFields):
    class Meta:
        abstract = True
    """
    Large set of methods
    """
    def method1(self): pass
    def method2(self): pass
    def method3(self): pass
    ...
    def methodN(self): pass

class BigModel(BigMethods):
    pass
  • Как это повлияет на производительность?
  • Сколько стоит один уровень наследования в python?
  • Влияет ли метаклассы на стоимость наследования?

1 Ответ

3 голосов
/ 23 марта 2012

Если в вашей модели есть такие последовательные поля, решение заключается не в наследовании, а в разбивке этих полей на отдельные модели и создании отношения один ко многим. С вашими примерами моделей трудно разобраться, поэтому я буду использовать один из проекта, над которым я работал.

Оригинальная модель выглядела примерно так:

class Page(models.Model):
    title = models.CharField(max_length=256)
    section_1_title = models.CharField(max_length=256)
    section_1_content = models.TextField()
    section_2_title = models.CharField(max_length=256)
    section_2_content = models.TextField()
    section_3_title = models.CharField(max_length=256)
    section_3_content = models.TextField()
    ...

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

class Page(models.Model):
    title = models.CharField(max_length=256)

class Section(models.Model):
    page = models.ForeignKey(Page, related_name='sections')
    title = models.CharField(max_length=256)
    content = models.TextField()
    order = models.PositiveIntegerField()

    class Meta:
        ordering = ['order']
        order_with_respect_to = 'page'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...