абстрактные модели django против регулярного наследования


кроме синтаксиса, в чем разница между использованием абстрактной модели django и использованием простого наследования Python с моделями django? Плюсы и минусы?

UPDATE: я думаю, что мой вопрос был неправильно понят, и я получил ответы на разницу между абстрактной моделью и классом, который наследует от django.децибел.модели.Модель. Я действительно хочу знать разницу между классом модели, который наследует от абстрактного класса django (Meta: abstract = True) и a простой класс Python, который наследует от say, ' object '(а не модели.Модель.)

вот пример:

class User(object):
   first_name = models.CharField(..

   def get_username(self):
       return self.username

class User(models.Model):
   first_name = models.CharField(...

   def get_username(self):
       return self.username

   class Meta:
       abstract = True

class Employee(User):
   title = models.CharField(...
5 59

5 ответов:

Я на самом деле хочу знать разницу между модели класса, который наследует от абстрактного класса django (Meta: abstract = True) и a простой класс Python, который наследует от say, 'object' (а не модели.Модель.)

Django будет генерировать только таблицы для подклассов models.Model, так бывший...

class User(models.Model):
   first_name = models.CharField(max_length=255)

   def get_username(self):
       return self.username

   class Meta:
       abstract = True

class Employee(User):
   title = models.CharField(max_length=255)

...приведет к созданию одной таблицы, вдоль строк...

CREATE TABLE myapp_employee
(
    id         INT          NOT NULL AUTO_INCREMENT,
    first_name VARCHAR(255) NOT NULL,
    title      VARCHAR(255) NOT NULL,
    PRIMARY KEY (id)
);

...а последний...

class User(object):
   first_name = models.CharField(max_length=255)

   def get_username(self):
       return self.username

class Employee(User):
   title = models.CharField(max_length=255)

...не приведет к созданию каких-либо таблиц.

вы можете использовать множественное наследование, чтобы сделать что-то вроде этого...

class User(object):
   first_name = models.CharField(max_length=255)

   def get_username(self):
       return self.username

class Employee(User, models.Model):
   title = models.CharField(max_length=255)

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

CREATE TABLE myapp_employee
(
    id         INT          NOT NULL AUTO_INCREMENT,
    title      VARCHAR(255) NOT NULL,
    PRIMARY KEY (id)
);

абстрактная модель создает таблицу со всем набором столбцов для каждого дочернего элемента, в то время как использование "простого" наследования Python создает набор связанных таблиц (он же "наследование нескольких таблиц"). Рассмотрим случай, в котором у вас есть две модели:

class Vehicle(models.Model):
  num_wheels = models.PositiveIntegerField()


class Car(Vehicle):
  make = models.CharField(…)
  year = models.PositiveIntegerField()

если Vehicle это абстрактная модель, у вас будет одна таблица:

app_car:
| id | num_wheels | make | year

однако, если вы используете простое наследование Python, у вас будет две таблицы:

app_vehicle:
| id | num_wheels

app_car:
| id | vehicle_id | make | model

здесь vehicle_id это ссылка на a строку app_vehicle это также будет иметь количество колес для автомобиля.

теперь, Django будет положить это вместе красиво в форме объекта, так что вы можете получить доступ num_wheels как атрибут Car, но базовое представление в базе данных будет отличаться.


обновление

чтобы решить ваш обновленный вопрос, разница между наследованием от абстрактного класса Django и наследованием от Python object это то, что первый рассматривается как a объект базы данных (поэтому таблицы для него синхронизируются с базой данных) и он имеет поведение Model. Наследование от простого Python object не дает классу (и его подклассам) ни одного из этих качеств.

просто хотел добавить что-то, что я не видел в других ответах.

в отличие от классов python,скрытие имени Поля не разрешено С моделью наследования.

например, я экспериментировал проблемы с прецедентом следующим образом:

у меня была модель, унаследованная от auth Джанго PermissionMixin:

class PermissionsMixin(models.Model):
    """
    A mixin class that adds the fields and methods necessary to support
    Django's Group and Permission model using the ModelBackend.
    """
    is_superuser = models.BooleanField(_('superuser status'), default=False,
        help_text=_('Designates that this user has all permissions without '
                    'explicitly assigning them.'))
    groups = models.ManyToManyField(Group, verbose_name=_('groups'),
        blank=True, help_text=_('The groups this user belongs to. A user will '
                                'get all permissions granted to each of '
                                'his/her group.'))
    user_permissions = models.ManyToManyField(Permission,
        verbose_name=_('user permissions'), blank=True,
        help_text='Specific permissions for this user.')

    class Meta:
        abstract = True

    # ...

тогда у меня был мой миксин, который среди прочего я хотел, чтобы он переопределил related_name на

основное различие заключается в том, как создаются таблицы баз данных для моделей. Если вы используете наследование без abstract = True Django создаст отдельную таблицу как для родительской, так и для дочерней модели, которая содержит поля, определенные в каждой модели.

если вы используете abstract = True для базового класса Django будет создавать таблицу только для классов, которые наследуются от базового класса - независимо от того, определены ли поля в базовом классе или наследующем классе.

плюсы и минусы зависят от архитектуры вашего приложения. Приведены следующие примеры моделей:

class Publishable(models.Model):
    title = models.CharField(...)
    date = models.DateField(....)

    class Meta:
        # abstract = True

class BlogEntry(Publishable):
    text = models.TextField()


class Image(Publishable):
    image = models.ImageField(...)

если Publishable класс не абстрактный Django создаст таблицу для publishables со столбцами title и date и отдельные таблицы для BlogEntry и Image. Преимущество этого решения будет заключаться в том, что вы можете запросить через все publishables для полей, определенных в базовой модели, независимо от того, являются ли они записями в блоге или изображениями. Но поэтому Django придется делать объединения, если вы, например, делаете запросы для изображений... Если сделать Publishableabstract = True Django не будет создавать таблицу для Publishable, но только для записей в блоге и изображений, содержащих все поля (также унаследованные). Это было бы удобно, потому что никакие соединения не понадобятся для такой операции, как get.

см. Также документация Django по наследованию модели.

основное различие заключается в том, когда вы наследуете класс User. Одна версия будет вести себя как простой класс, а другая будет вести себя как Django modeel.

Если вы наследуете базовую версию "объекта", ваш класс Employee будет просто стандартным классом, а first_name не станет частью таблицы базы данных. Вы не можете создать форму или использовать с ней любые другие функции Django.

Если вы наследуете модели.Версия модели, ваш класс сотрудника будет иметь все методы а Джанго модель, и он унаследует поле first_name как поле базы данных, которое можно использовать в форме.

согласно документации, an Абстрактная Модель " предоставляет способ учета общей информации на уровне Python, в то же время создавая только одну таблицу базы данных для каждой дочерней модели на уровне базы данных."