абстрактные модели 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 ответов:
Я на самом деле хочу знать разницу между модели класса, который наследует от абстрактного класса 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
. Наследование от простого Pythonobject
не дает классу (и его подклассам) ни одного из этих качеств.
просто хотел добавить что-то, что я не видел в других ответах.
в отличие от классов 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 придется делать объединения, если вы, например, делаете запросы для изображений... Если сделатьPublishable
abstract = True
Django не будет создавать таблицу дляPublishable
, но только для записей в блоге и изображений, содержащих все поля (также унаследованные). Это было бы удобно, потому что никакие соединения не понадобятся для такой операции, как get.см. Также документация Django по наследованию модели.
основное различие заключается в том, когда вы наследуете класс User. Одна версия будет вести себя как простой класс, а другая будет вести себя как Django modeel.
Если вы наследуете базовую версию "объекта", ваш класс Employee будет просто стандартным классом, а first_name не станет частью таблицы базы данных. Вы не можете создать форму или использовать с ней любые другие функции Django.
Если вы наследуете модели.Версия модели, ваш класс сотрудника будет иметь все методы а Джанго модель, и он унаследует поле first_name как поле базы данных, которое можно использовать в форме.
согласно документации, an Абстрактная Модель " предоставляет способ учета общей информации на уровне Python, в то же время создавая только одну таблицу базы данных для каждой дочерней модели на уровне базы данных."