I keep getting an error when i try to pass a user to a project model as its created. I am able to access the user object when one is logged in via params["user"] and i get an error message
What i am trying to do is just the same as the app engine ndb and get to match the user to the record they created such that when they login they are able to view only their records. So am trying to get someone to login and based on their login we can use their information to save a project they create.
The following is my piece of code to the projects model and 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"
The code to the api is as follows.
@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)
This is the error am getting within my code now
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()
I think the problem may be in create_project()
. The traceback shows:
user=ndb.Key('User', user.key),
This wouldn't be the right way to build a key, you need to pass a key ID to the Key() contructor, not a key:
user=ndb.Key('User', <user_key_id>),
The updated code snippet shows an attempt in that direction.
But unless I misread your code user
is obtained from the request parameters at that moment:
user = params["user"]
Which would mean that user
may not be an ndb entity (I don't think you can directly pass ndb entities as request parameters). Try displaying it in a log msg to check that. You may need to either:
obtain/create the actual user
ndb entity and get its key:
user=user.key.id(),