Настройка двух разных типов пользователей в Django 1.5/1.6
Обратите внимание - это обновленная версия моего первоначального вопроса по этому вопросу, но заслуживает того, чтобы вас снова попросили с изменением того, как Django занимается с пользователями и аутентификации.
Я работаю над сайтом с двумя разными пользователями - позвоните им Customers
и Store Owners
. Оба регистрируются на сайте, но имеют очень разную функциональность. Customers
просто имеет один профиль и может делать покупки среди магазинов, которые им нравятся. Store Owners
имеют одну учетную запись, но могут иметь доступ к нескольким магазинам, и каждый магазин может иметь несколько Store Owners
.
Точные детали моделей не имеют значения, но для двух типов пользователей потребуются очень разные поля. Модели идеально выглядели бы примерно так:
Customer
email (username)
password
name
address
time_zone
preferred_shipping
favorite_stores (many-to-many field)
...
Store Owner
email (username)
password
name
balance
stores_owned (many-to-many field on Stores)
stores_managed (many-to-many field on Stores)
...
Первоначально, когда у Django была плохая пользовательская поддержка, у меня был класс
UserProfile
с некоторыми дополнительными полями с
OneToOne
на
User
, а затем дополнительные классы
Customer
и
StoreOwner
, которые были
OneToOne
на
UserProfile
. Это не очень хорошо работает.
Учитывая изменения в Django 1.5/1.6, я пытаюсь найти лучший способ структурировать это. Сейчас у меня есть следующее:
class CustomerUser(AbstractBaseUser):
...
class StoreOwnerUser(AbstractBaseUser):
...
Но поскольку у пользователя будет два типа пользователей, я не могу установить AUTH_USER_MODEL
только один из них.
Каков наилучший способ структурирования этого, так что у меня могут быть два разных типа пользователей с разными полями, без каких-либо проблем с аутентификацией пользователя, созданием пользователя или администратором?
Кроме того, как я могу определить только логин, является ли этот пользователь CustomerUser
или StoreOwnerUser
?
Ответы
Ответ 1
Похоже, что есть некоторые общие функции и необычные функции для ваших типов пользователей. Если в ваших пользовательских типах есть общие черты, то пользовательская модель Django по умолчанию не поддерживается из коробки, вы должны подклассифицировать ее напрямую.
Добавление дополнительных, необычных функций к вашим типам пользователей лучше всего делать не путем подкласса, а с помощью профиля. Мое обоснование для этого состоит в том, что ваша аутентификация для этих типов пользователей принципиально не меняется, но информация о пользователе выполняется в зависимости от типа пользователя. Чтобы разместить это, вы создаете отдельную модель с этими подробностями и ссылаетесь на свой класс User как отношение OneToOne/ForeignKey (в зависимости от вашего дизайна).
Вы можете внести изменения в свой процесс создания пользователя, чтобы определить, какой тип пользователя он должен быть, и установить его связанный OneToOneField/ForeignKey (в зависимости от вашего дизайна) с соответствующей моделью типа клиента.
Таким образом, вы должны иметь только один AUTH_USER_MODEL, и вы сможете обрабатывать детали для разных типов клиентов.
Ответ 2
Каков наилучший способ структурирования этого, чтобы у меня было два разные типы пользователей с разными полями, не заставляя меня проблемы в аутентификации пользователя, создание пользователя или администратор?
У вас фактически есть только один тип пользователей. Просто у некоторых пользователей есть определенные свойства, а другие нет. Подумайте, как у django есть "пользователи" и "администраторы". Они являются экземплярами одной и той же модели, но с разными свойствами и разрешениями.
Вы должны подойти аналогично. У вас есть одна модель пользователя для всего вашего приложения. Вы можете установить свойства/методы в своем пользовательском классе, чтобы определить, какие флаги установлен этим пользователем (что определяло бы "тип" пользователя).
Кроме того, как я могу определить только логин, является ли этот пользователь a CustomerUser
или StoreOwnerUser
?
Вы можете использовать декоратор user_passes_test
, который принимает аргумент, являющийся именем функции, и обрабатывает только обработку, если функция вернется значение истины.
Ответ 3
- Создайте BaseUser, который расширяет базу данных Django.
-
Создайте два подкласса, названный CustomerUser и StoreOwnerUser, который расширяет BaseUser
from django.db import models
from django.contrib.auth.models import AbstractUser
class BaseUser(AbstractUser):
# all the common fields go here, for example:
email = models.EmailField(max_length=10,unique=True)
name = models.CharField(max_length=120)
class StoreOwnerUser(BaseUser):
# All Store Owner specific attribute goes here
balance = models.some_balance_field()
stores_owned = models.some_stores_owned_field()
class Meta:
verbose_name = 'Store Owner'
class CustomerUser(BaseUser):
# All Customer specific attribute goes here
customer_id = models.CharField(max_length=30, unique=True)
address = models.some_address
time_zone = models.something...
...
class Meta:
verbose_name = 'Customer'