7

私は別のユーザーであるスポンサーのキーを使用して、ユーザーのスポンサーが誰であるかを示します。これにより、スポンサーを持つユーザーのデータストアにリンクが作成されます。これは最大で1つですが、スポンサーは次のような多くのユーザーをスポンサーできます。この場合、他の3人のユーザーを後援したID2002:

ここに画像の説明を入力してください

この場合、このクエリは私が望むことを実行します:SELECT * FROM User where sponsor =KEY('agtzfmJuYW5vLXd3d3ILCxIEVXNlchjSDww')しかし、Pythonでそれをプログラムする方法がわからないので、データストアに対してのみ使用できます。同じフィールドのキーと同じユーザーを持つユーザーのセットを照合する場合、キーでクエリするにはどうすればよいですか?私のモデルのユーザーは最大で1人のスポンサーを持つことができ、特定の人が誰をスポンサーしているかを知りたいだけです。これはユーザーのリストであり、次に彼らが順番にユーザーをスポンサーしていて、それについても質問したいと思います。

フィールドスポンサーはキーであり、データストア内のスポンサーへのリンクがあります。user2.sponsor = user1.keyのようにキーを設定しました。次に、次のようなクエリでスポンサーされているuser1をすべて検索します。

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

しかし、スポンサーはタイプキーのフィールドであるため、たとえば、アクティブユーザーがスポンサーである人々のリストを確認するためにそれを照合する方法や、第2世代にもリンクがある場合にツリーになる方法がわかりません。このユーザーがスポンサーであり、次に第2世代であるユーザーのリストを選択するにはどうすればよいですか?関係を単純にu1=u2.key、つまりuser2.sponsor=user1.keyのようにモデル化したとき。ヒントをありがとう

次の回避策は悪い習慣ですが、私の最後で唯一の手段です。

def get(self):
    auser = self.auth.get_user_by_session()
    realuser = auth_models.User.get_by_id(long( auser['user_id'] ))
    q = auth_models.User.query()
    people = []
    for p in q:
      try:
        if p.sponsor == realuser.key:
           people.append(p)
      except Exception, e:
        pass
    if auser: 
        self.render_jinja('my_organization.html', people=people, user=realuser,)

アップデート

問題は、キープロパティが不要であり、コードのバグだと思うときに、GuidoVanRossumがこれをndbのバグとして報告していることです。これが私が現在使用しているものです。これは、プログラマー、テスター、管理者を除く組織内のすべての実際のユーザーがユーザーIDであるスポンサーIDを持っている必要があるため、非常に受け入れられるソリューションです。

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()
    ...
4

2 に答える 2

5

ユーザーモデルはNDBExpandoであり、クエリを実行するのは少し難しいです。

ドキュメントから

もう1つの便利なトリックは、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,)
于 2012-01-07T20:08:18.000 に答える
2

オプション#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)
于 2012-01-07T21:17:47.373 に答える