Как создать запрос на соответствие ключей? - PullRequest
7 голосов
/ 07 января 2012

Я использую ключ другого пользователя, спонсора, чтобы указать, кто является спонсором пользователя, и он создает ссылку в хранилище данных для тех пользователей, у которых есть спонсор, и он может быть не более одного, но спонсор может спонсироватьмногим пользователям нравится в этом случае ID 2002, который спонсировал трех других пользователей:

enter image description here

В этом случае этот запрос делает то, что я хочу: SELECT * FROM User where sponsor =KEY('agtzfmJuYW5vLXd3d3ILCxIEVXNlchjSDww'), но я не знаю, какЗапрограммируйте это на python, я могу использовать его только в хранилище данных.Как я могу выполнить запрос по ключу, если я хочу сопоставить набор пользователей, у которых тот же пользователь, что и ключ, в том же поле?У пользователя в моей модели может быть не более одного спонсора, и я просто хочу знать, кого спонсировал конкретный человек, который может быть списком пользователей, а затем они спонсируют пользователей, в свою очередь, к которым я также хочу обратиться.

Полевой спонсор является ключевым и имеет ссылку на спонсора в хранилище данных.Я установил ключ точно так же, как user2.sponsor = user1.key, и теперь я хочу найти всех пользователей user1 с запросом, который должен быть таким же, как

User.All().filter('sponsor = ', user1.key)

, но спонсорполе типа ключ, поэтому я не знаю, как сопоставить его, например, список людей, спонсором которых является активный пользователь, и как он становится деревом, когда во втором поколении также есть ссылки.Как выбрать список пользователей, спонсором которого является этот пользователь, а затем второе поколение?Когда я смоделировал отношение просто как u1 = u2.key т.е. user2.sponsor = user1.key.Спасибо за любую подсказкучто Гвидо Ван Россум сообщил об этом как об ошибке в ndb, когда я думаю, что это ошибка в моем коде.Вот что я сейчас использую, и это очень приемлемое решение, поскольку каждый реальный пользователь в организации, за исключением, возможно, программистов, тестировщиков и администраторов, должен иметь идентификатор спонсора, который является идентификатором пользователя.

from ndb import query
class Myorg(NewBaseHandler):
    @user_required
    def get(self):
        user = auth_models.User.get_by_id(long(self.auth.get_user_by_session()['user_id']))
    people = auth_models.User.query(auth_models.User.sponsor == user.key).fetch()
        self.render_jinja('my_organization.html', people=people,
                              user=user) 

class User(model.Expando):
    """Stores user authentication credentials or authorization ids."""

    #: The model used to ensure uniqueness.
    unique_model = Unique
    #: The model used to store tokens.
    token_model = UserToken
    sponsor = KeyProperty()
    created = model.DateTimeProperty(auto_now_add=True)
    updated = model.DateTimeProperty(auto_now=True)
    # ID for third party authentication, e.g. 'google:username'. UNIQUE.
    auth_ids = model.StringProperty(repeated=True)
    # Hashed password. Not required because third party authentication
    # doesn't use password.
    password = model.StringProperty()
    ...

Ответы [ 2 ]

5 голосов
/ 08 января 2012

Модель User - это NDB Expando, который немного сложнее запрашивать.

Из документов

Еще один полезный трюк - это запрос Expando.вид динамического свойства.Вы не сможете использовать class.query (class.propname == value), поскольку у класса нет объекта свойства.Вместо этого вы можете использовать класс ndb.query.FilterNode для создания выражения фильтра следующим образом:

from ndb import model, query

class X(model.Expando):
  @classmethod
  def query_for(cls, name, value):
    return cls.query(query.FilterNode(name, '=', value))

print X.query_for('blah', 42).fetch()

Так что попробуйте:

form ndb import query

def get(self):
    auser = self.auth.get_user_by_session()
    realuser = auth_models.User.get_by_id(long( auser['user_id'] ))
    people = auth_models.User.query(query.FilterNode('sponsor', '=', realuser.key)).fetch()
    if auser: 
        self.render_jinja('my_organization.html', people=people, user=realuser,)
2 голосов
/ 08 января 2012

Опция # 2

Эта опция немного чище.Вы делите модель на подклассы и передаете ее местоположение в webapp2.Это позволит вам добавлять пользовательские атрибуты и пользовательские запросы к классу.

# custom_models.py
from webapp2_extras.appengine.auth.models import User
from google.appengine.ext.ndb import model

class CustomUser(User):
    sponsor = model.KeyProperty()

    @classmethod
    def get_by_sponsor_key(cls, sponsor):
        # How you handle this is up to you. You can return a query 
        # object as shown, or you could return the results.
        return cls.query(cls.sponsor == sponsor)

# handlers.py
def get(self):
    auser = self.auth.get_user_by_session()
    realuser = custom_models.CustomUser.get_by_id(long( auser['user_id'] ))
    people = custom_models.CustomUser.get_by_sponsor_key(realuser.key).fetch()
    if auser:
        self.render_jinja('my_organization.html', people=people, user=realuser,)


# main.py
config = {
    # ...
    'webapp2_extras.auth': {
        # Tell webapp2 where it can find your CustomUser
        'user_model': 'custom_models.CustomUser',
    },
}

application = webapp2.WSGIApplication(routes, config=config)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...