I am developing a web application using google appengine.
I am trying to update an existing entry in the table but my post operation does not seem to be working.
post script:
r = requests.post("http://localhost:8080", data={'type': 'user', 'id':
'11111', 'name': 'test'})
When running the script there are no errors in the console and when prining r.text I can see the updated name but the page on localhost does not show the updated name and the datastore user still has its previous name.
My model for the main page is:
class Page(webapp2.RequestHandler):
def get(self):
...
def post(self):
user = User().get_user(self.request.get('id')) // query user from data store
user.name = self.request.get('name')
user.put()
// update jinja template
self.request.get('id') is a string. You want to use an integer for the id, or build a key (I am assuming you are using ndb):
user = ndb.Key('User', int(self.request.get('id'))).get()
Related
I am trying to implement a 'remember me' feature on the login page.
This is the logic I have in mind: Store sessions in the datastore,
pass the session id/key to the client so that next time the user visits
the site, i get information from the datastore with the key the client has
I was about to do something like this:
class Session(ndb.Model):
username = ndb.StringProperty()
email = ndb.StringProperty()
if request.get('rememberme'):
session = Session()
session.email = 'john#doe.com'
session.username = 'jon snow'
key = session.put()
# send `key` back to client and store in a cookie, so
# when client visits the site again, get the session
# values from the datastore
self.response.write(key.id())
But I'm using this snippet from the docs to handle my sessions:
class BaseHandler(webapp2.RequestHandler):
def dispatch(self):
self.session_store = sessions.get_store(request=self.request)
try:
webapp2.RequestHandler.dispatch(self)
finally:
self.session_store.save_sessions(self.response)
#webapp2.cached_property
def session(self):
return self.session_store.get_session(name='foo', backend='datastore')
This too ,inserts data into the datastore under the 'Session' Kind.
So it feels like I'd be doing redudant work if I were to manually store sessions in the datastore as well.
When using webapp2's session with datastore as the backend, how can I know that session's id/key?
I have an application which is school based. Each tenant is a different school and to access the application all users for each school have the same password.
Alongside this each school user has to have a google email if they want access to the application. So the application first checks they are a google user, checks wether they are a school user and finally checks that their google email is in the school user list before they are allowed access to any page.
The school user part is using session data from webapp2 sessions to ensure each request they have appropriate access
class Handler(webapp2.RequestHandler):
def dispatch(self):
# Get a session store for this request.
self.session_store = sessions.get_store(request=self.request)
try:
# Dispatch the request.
webapp2.RequestHandler.dispatch(self)
finally:
# Save all sessions.
self.session_store.save_sessions(self.response)
#webapp2.cached_property
def session(self):
# Returns a session using the default cookie key.
return self.session_store.get_session()
When a user logins I check the password then create a session which checks their password / user combination every request.
def check_u(self):
try:
uid = self.session.get('user')
parent = self.session.get('school-id')
udl = m.models.User.by_id(int(uid),parent)
if uid and udl:
return udl
else:
return False
except (TypeError,AttributeError):
return False
A parent datastore entity for each different school is used called MetaSchool which I have been currently using to ensure that there is no data leak across schools. Each datastore entry uses this parent session key as a way of setting the datastore entry with MetaSchool as parent then using this session key again to read back this data.
This method works but is onerous. I would like to use namespace as a way of separating the data but would like to use the Metaschool id as the name.
def namespace_manager_default_namespace_for_request():
### Here I need to get ------ parent = self.session.get('school-id')
### use this session to gain the MetaSchool key id
### Set this as the namespace name
Basically trying to emulate from the docs the below scenario
from google.appengine.api import users
def namespace_manager_default_namespace_for_request():
# assumes the user is logged in.
return users.get_current_user().user_id()
I am having difficulty getting the session data from Handler object???
Any thoughts
This is what I came up with.
from google.appengine.api import namespace_manager
from webapp2_extras import sessions
def namespace_manager_default_namespace_for_request():
session = sessions.get_store()
s = session.get_session()
name = s.get('key')
if name:
return name
else:
return namespace_manager.set_namespace('string')
I have just started working on Django, angularjs , The issue currently i am facing is I have created a model in django as following
**class Car_Booking(models.Model):
owner = models.ForeignKey('auth.User', related_name='booking_user')
car_id=models.IntegerField(max_length=4,default=1)
extra_field1=models.CharField(max_length=100,null=True)
extra_field2=models.CharField(max_length=50,null=True)
extra_field3=models.CharField(max_length=50,null=True)**
The Serializer is as following
**class CarBookingSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
class Meta:
model = Car_Booking
fields = ('car_id','owner','extra_field1','extra_field2','extra_field3')**
And view is as following
**class CarBookingViewSet(viewsets.ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
Additionally we also provide an extra `highlight` action.
"""
queryset = Car_Booking.objects.all()
serializer_class = CarBookingSerializer
permission_classes = (permissions.AllowAny,
def perform_create(self, serializer):
serializer.save(owner=self.request.user)**
Now i developed a front end on Angularjs, the templelates i built were on the same server say localhost:8000 so when i call the view to insert the data by passing car_id, extra_field1, extra_field2 and extra_field 3 it gets saved successfully because i already get logged in and saved the user information into the cookies so i guess the Owner field is resolved automatically. Now when i call the same view from the IONIC framework on server localhost:5000(port is differnt) it give me the error, "Owner must be a user instance". I have searched a lot but can not find how to send the user authentication information, or save it accross the domains. Secondly i have tried to pass the owner_id but when i write the owner_id into the serializer it says "Owner_id is not a valid modlebase" but while calling throught the command prompt i can set the owner_id, Any Help on the following questions
***1. How can i send the username and password along the Post URL
How can i set the owner_id instead of OWNER object instance.***
Regards
Hopefully someone can help. I am building an app on Google app engine and trying to pass the credentials of an authenticated user to the push task Handler. I am using the OAuth2DecoratorFromClientSecrets library to create the decorator which seems to store the credentials for the user in the datastore. It stores it with a key name of something like "110111913122157971566". My problem is that I cant seem to find a way to figure out what that key name is so that I can retrieve it using the StorageByKeyName method from within my worker handler. The documentation I have read uses the user_id as the key name but this doesnt work for me as the credentials are not stored with the user_id as the key name, however if I hard code the key name then the code does work. I am aware that I could run the copy code from within the Submit handler but need to run it as a separate task. Below is a sample of my code, thanks for any help you can provide:
JINJA_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
extensions=['jinja2.ext.autoescape'],
autoescape=True)
SCOPES =['https://www.googleapis.com/auth/drive']
decorator = OAuth2DecoratorFromClientSecrets(
os.path.join(os.path.dirname(__file__),
'client_secrets.json'),
' '.join(SCOPES)
)
class MainPage(webapp2.RequestHandler):
def get(self):
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
url_linktext = 'Logout'
template_values = {'url': url,
'url_linktext': url_linktext,
}
template = JINJA_ENVIRONMENT.get_template('index.html')
self.response.write(template.render(template_values))
else:
self.redirect(users.create_login_url(self.request.uri))
class Submit(webapp2.RequestHandler):
#decorator.oauth_required
def post(self):
taskqueue.add(url='/worker', params={'user_id' : users.get_current_user().user_id()})
self.response.write('<html><body>You wrote:<pre>')
self.response.write(users.get_current_user().user_id())
self.response.write('</pre></body></html>')
class Worker(webapp2.RequestHandler):
def post(self):
user_id = self.request.get('user_id')
credentials = StorageByKeyName(CredentialsModel, user_id , 'credentials').get()
http = httplib2.Http()
http = credentials.authorize(http)
service = build('drive', 'v2',http=http)
fileId = 'actual file_id of drive file here'
copied_file = {'title': 'My New Test Doc2'}
new_file = service.files().copy(fileId=fileId,body=copied_file).execute(http=http)
application = webapp2.WSGIApplication([
('/', MainPage),
('/submit', Submit),
('/worker', Worker),
(decorator.callback_path, decorator.callback_handler()),
], debug=True)
First, remove the http=decorator.http at the top level - it doesn't appear to be used and should only be used from inside the decorated method.
I'm not certain, but looking at the decorator code I think it is is keying based on the user_id(). Your code is displaying that, but the parameter you are passing to the task isn't. Try {'user_id' : users.get_current_user().user_id()}.
I have a web app on GAE which uses a ndb database where each entity has as properties user informations and two string, the Entity class is like the one below
class UserPlus(ndb.Model):
user = ndb.UserProperty()
dogName = ndb.StringProperty(indexed=False)
catName = ndb.StringProperty(indexed=False)
The Main Page check if there's already an entity corresponding to that user, and if yes displays the value of the strings dogName and catName.
Then there's a form where users can update the values of dogName and catName . This performs a POST request to another page, the method below update the entiy
def post(self):
currentUser = users.get_current_user()
up = UserPlus.query(UserPlus.user==currentUser).get()
up.dogName = self.request.get('dog_name')
up.catName = self.request.get('cat_name')
weatherUser.put()
self.redirect('/')
But when I'm redirected to the Main Page, the values of dogName and catName are not updated until I refresh the page. I found that by calling the put() method two times instead of one, in the same position, this doesn't occur anymore, but I don't have clear why.
Am I doing something wrong or it's how ndb is supposed to work?
As Guido suspects and bossylobster/Fred Saur answered on my old question here - Should I expect stale results after redirect on local environment? - most likely eventual consistency problem.