有没有办法使用 cloud-ndb 将用户与项目正确匹配

Is there a way to properly match a user to a project using cloud-ndb

当我尝试将用户传递给创建的项目模型时,我总是收到错误消息。 当一个人通过 params["user"] 登录时,我能够访问用户对象,但我收到一条错误消息

我正在尝试做的与应用程序引擎 ndb 相同,并将用户与他们创建的记录相匹配,这样当他们登录时,他们只能查看他们的记录。因此,我试图让某人登录,并根据他们的登录信息,我们可以使用他们的信息来保存他们创建的项目。

以下是我的项目模型代码和api

from flask import jsonify, make_response
import re
from datetime import datetime

from google.cloud import ndb
from google.cloud import storage
#from dateutil import tz
from models.v1.user import User
from models import get_db
class Project(ndb.Model):
    user = ndb.KeyProperty(kind=User)

    funds_raised = ndb.FloatProperty(default=0.0)
    live_date = ndb.DateTimeProperty()
    finish_date = ndb.DateTimeProperty()

    created_on = ndb.DateTimeProperty(auto_now_add=True)
    project_name = ndb.StringProperty(default='New Project')
    project_image = ndb.BlobKeyProperty()
    project_image_url = ndb.StringProperty(default='')
    project_created_by = ndb.StringProperty(default='')
    project_category = ndb.StringProperty(default='')
    project_location = ndb.StringProperty(default='')
    project_link = ndb.StringProperty(default='')
    project_duration = ndb.StringProperty(default='')

    @property
    def project_url_name(self):
        if not self.project_url_name_unique_key:
            return None

        return self.project_url_name_unique_key.id().rsplit(':', 1)[1]

    # class methods (ordered by alphabet)
    @classmethod
    def create(cls, primary_contact_first_name, primary_contact_surname, primary_contact_email, project_name, project_status):
        with client.context():
            project = cls( primary_contact_first_name=primary_contact_first_name, primary_contact_surname=primary_contact_surname, primary_contact_email=primary_contact_email, 
                            project_name=project_name, project_status=project_status)
            project.put()

            if project:

                return True, project, "Success"  # succes, project, message
            else:
                return False, project, "Project not created"

api的代码如下。

@login_required
def create_project(**params):

    if request.method == "POST":
        user = params["user"]
        details = user.to_dict()

        success, project, message = Project.create(
            user = ndb.Key('User', user.get_id)
            primary_contact_first_name=details.get('first_name'),
            primary_contact_surname=details.get('last_name'),
            primary_contact_email=details.get('email_address'),
            project_name='New Project',
            project_status=0
        )

        if success:
            return make_response(jsonify({"Message" : message, "Project" : project.to_dict() }))
        else:
            return abort(403, description=message)

这是我的代码中出现的错误

File "/home/lenny/Desktop/flask_gae/utils/decorators.py", line 64, in wrapper
    return func(**params)
  File "/home/lenny/Desktop/flask_gae/handlers/campaigns/main.py", line 33, in create_project
    user=ndb.Key('User', user.key),
  File "/home/lenny/Desktop/flask_gae/env/lib/python3.7/site-packages/google/cloud/ndb/key.py", line 285, in __new__
    client = context_module.get_context().client
  File "/home/lenny/Desktop/flask_gae/env/lib/python3.7/site-packages/google/cloud/ndb/context.py", line 71, in get_context
    raise exceptions.ContextError()

认为问题可能在create_project()。追溯显示:

user=ndb.Key('User', user.key),

这不会是 the right way to build a key,您需要将密钥 ID 传递给 Key() 构造函数,而不是密钥:

user=ndb.Key('User', <user_key_id>),

更新后的代码片段显示了朝这个方向的尝试。

但是除非我看错了你的代码 user 是当时从请求参数中获取的:

user = params["user"]

这意味着 user 可能不是 ndb 实体(我认为您不能直接将 ndb 实体作为请求参数传递)。尝试在日志消息中显示它以进行检查。您可能需要:

  • 如图所示构建用户密钥(如果您知道其 ID)
  • 从可以通过请求参数传递的 urlsafe 字符串构造用户密钥,请参阅 (post 是关于 python2 ndb 客户端,但我认为云ndb 有类似的东西)
  • obtain/create 实际的 user ndb 实体并获取其密钥:

    user=user.key.id(),