Добавить ссылку на модель к существующей модели - PullRequest
3 голосов
/ 02 мая 2011

Я создал модуль, который обслуживает мою собственную систему аутентификации и пользователей.Это универсальный модуль, который я использую в разных приложениях.В этом модуле описана модель User, например:

class User(db.Model):
    email = db.EmailProperty()
    password = db.StringProperty()
    role = db.StringProperty(default=roles.USER)

. В любом отдельном приложении, где я использую этот модуль, я хотел бы создать дополнительную модель, которая описывает дополнительные поля, специфичные дляэто приложение выглядит так:

 class UserProfile(db.Model):
        first_name = db.StringProperty()
        last_name = db.StringProperty()
        company = db.StringProperty()

И мне нужно прикрепить UserProfile модель к User модели внутри моего нового приложения.Как мне это сделать без изменения кода внутри модуля, который является общим для всех приложений?

Ответы [ 3 ]

2 голосов
/ 02 мая 2011

Если бы у меня был пользовательский модуль, который я импортировал из нескольких проектов, я бы рассматривал этот общий модуль как base для создания своих приложений.

Таким образом, у вас может быть baseuser.py модуль, содержащий:

class UserModel(db.Model):
    email = db.EmailProperty()
    password = db.StringProperty()
    role = db.StringProperty(default=roles.USER)

Тогда в каждом проекте GAE у вас будет:

from baseuser import UserModel

class User(UserModel):
    first_name = db.StringProperty()
    last_name = db.StringProperty()
    company = db.StringProperty()

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

1 голос
/ 02 мая 2011

Таким образом, в любом отдельном приложении это, по-видимому, отношение один к одному. Таким образом, произвольно, где вы храните ссылку. Вы можете просто изменить свою модель UserProfile для ссылки на пользователя:

class UserProfile(db.Model):
        user = db.ReferenceProperty(User)
        first_name = db.StringProperty()
        last_name = db.StringProperty()
        company = db.StringProperty()

Затем в контроллере:

user = User.filter('email =', email).get()
profile = UserProfile.filter('user =', user).get()

В качестве альтернативы, если вы хотите, чтобы ссылка размещалась на объекте User, но не ломала приложения, которые не поддерживают профиль, вы можете сделать это:

class User(db.Model):
    email = db.EmailProperty()
    password = db.StringProperty()
    role = db.StringProperty(default=roles.USER)
    profile = db.ReferenceProperty()

Здесь вы указываете слабую ссылку на профиль пользователя. Это не обязательно, и если вы его заполняете, это не обязательно должна быть конкретная модель. Это позволяет дополнительно хранить ссылку на профиль без нарушения совместимости.

Наконец, вы можете вообще пропустить профиль и просто сделать свой объект User Expando .

0 голосов
/ 02 мая 2011

Все ли приложения совместно используют базу данных?В этом случае вы не можете сохранить UserProfile как поле модели User, поскольку у пользователя не всегда есть связанный профиль.Я бы сделал User полем UserProfile, чтобы он указывал на это обратно (UserProfile содержит пользователя), и внесу в индекс поле user UserProfile, чтобы вы могли быстро найти UserProfile для данного пользователя.1003 * Если вы просто заинтересованы в повторном использовании кода, но не в совместном использовании общей базы данных, вы можете сделать эти дополнительные поля условными в зависимости от приложения.Например:

class User(db.Model):
    email = db.EmailProperty()
    password = db.StringProperty()
    role = db.StringProperty(default=roles.USER)
    if APP_HAS_USER_PROFILES:
        first_name = db.StringProperty()
        last_name = db.StringProperty()
        company = db.StringProperty()

Тогда эти последние три поля появятся только в определенных приложениях.Я полагаю, что вы также можете наследовать UserProfile от пользователя, но я не уверен, что произойдет тогда (с точки зрения базы данных).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...