Ответ 1
Предупреждение: Django 1.5 очень новый, и люди все еще изучают его новые функции. Поэтому мой ответ - не что иное, как мое мнение, основанное на недавних исследованиях, чтобы ответить на этот вопрос.
Оба способа - это допустимые способы достижения результата с его преимуществами и недостатками.
Начнем с:
Второй вариант
- Без вложенных моделей, а не модульных.
AbstractBaseUser
, как сказано в названии, является абстрактной моделью и не имеет конкретной таблицы - Неиспользуемые поля
-
Вам нужно проверить user_type для любой итерации с моделью, которая использует дополнительные поля:
def foo(): if user.user_type == 'Private': # ... else: # ...
Результирующий SQL будет примерно следующим:
CREATE TABLE "myapp_user" (
"id" integer NOT NULL PRIMARY KEY,
"password" varchar(128) NOT NULL,
"last_login" datetime NOT NULL,
"email" varchar(254) NOT NULL UNIQUE,
"user_type" varchar(30) NOT NULL,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL,
"company_name" varchar(100) NOT NULL
);
Первая опция
- Вложенные модели с логическим разделением объектов
- Очень скудный
- Вы должны реализовать
BaseUserManager
для каждого дочернего , если вы хотите использоватьcreate_user
-подобные функции - Вы не можете получить доступ к подклассам с помощью простого
BaseUser.objects.all()
*
Результирующий SQL будет примерно следующим:
CREATE TABLE "myapp_baseuser" (
"id" integer NOT NULL PRIMARY KEY,
"password" varchar(128) NOT NULL,
"last_login" datetime NOT NULL,
"email" varchar(254) NOT NULL UNIQUE
);
CREATE TABLE "myapp_privateuser" (
"baseuser_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "myapp_baseuser" ("id"),
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL
);
CREATE TABLE "myapp_tradeuser" (
"baseuser_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "myapp_baseuser" ("id"),
"company_name" varchar(100) NOT NULL
);
* Представьте себе следующую ситуацию:
>>> BaseUser.objects.create_user('[email protected]', password='baseuser')
>>> PrivateUser.objects.create_user('[email protected]', password='privateuser', first_name='His', last_name='Name')
>>> TradeUser.objects.create_user('[email protected]', password='tradeuser', company_name='Tech Inc.')
>>> BaseUser.objects.all()
[<BaseUser: [email protected]>, <BaseUser: [email protected]>, <BaseUser: [email protected]>]
>>> PrivateUser.objects.all()
[<PrivateUser: [email protected]>]
>>> TradeUser.objects.all()
[<TradeUser: [email protected]>]
Таким образом, вы не можете напрямую извлекать экземпляры подклассов с помощью BaseUser.objects.all()
. Существует отличный отличный пост в блоге Джеффом, объясняющим, как выполнить "автоматическое понижение" от BaseUser
до его дочерних элементов.
Тем не менее, вы должны учитывать преимущества и недостатки каждого подхода и их влияние на ваш проект. Когда вовлеченная логика мала (как в описанном примере), оба подхода действительны. Но в более сложном сценарии подход может быть лучше, чем другой. Я бы выбрал вариант с несколькими моделями, потому что он более расширяемый.