How to reuse a function or class in Django - python

This is my class TimesheetListApiV2 there are lots of such kind of classes.
#valid_accesstoken_check
class TimesheetListApiV2(APIView):
def get(self, request):
try:
accesstoken=AccessToken.objects.get(
token=self.request.META.get('HTTP_AUTHORIZATION').replace('Bearer ', '')
)
except ObjectDoesNotExist:
return Response (
{
"status" : False,
"error" : "Wrong Access Token",
"error_message":"You have provided wrong access token.",
}
)
Now in all my classes this piece of code is there.
try:
accesstoken=AccessToken.objects.get(
token=self.request.META.get('HTTP_AUTHORIZATION').replace('Bearer ', '')
)
except ObjectDoesNotExist:
return Response (
{
"status" : False,
"error" : "Wrong Access Token",
"error_message":"You have provided wrong access token.",
}
)
I want to write a function or class where to reuse that code instead of writing it. But it should be workable even request should be pass. Even in future i am going to add more such code which should be reused.
I tried to make this decorators.py
from django.core.exceptions import ObjectDoesNotExist
from oauth2_provider.models import AccessToken
def valid_accesstoken_check(function):
def wrap(request, *args, **kwargs):
try:
accesstoken=AccessToken.objects.get(
token=self.request.META.get('HTTP_AUTHORIZATION').replace('Bearer ', '')
)
except ObjectDoesNotExist:
return Response (
{
"status" : False,
"error" : "Wrong Access Token",
"error_message":"You have provided wrong access token.",
}
)
wrap.__doc__ = function.__doc__
wrap.__name__ = function.__name__
return wrap
But it is giving error
path('timesheet/list', views.TimesheetListApiV2.as_view(), name='api_v2_timesheet_list'),
AttributeError: 'function' object has no attribute 'as_view'

Your decorator should apply to the get method, not the class itself:
class TimesheetListApiV2(APIView):
#valid_accesstoken_check
def get(self, request):
...

Related

how to loop through a python list of nothing

I am trying to create a online class and want to loop through the list of the classes to see if he/she been registered or not
problem is if the list be empty it will return an error
I am using django and django-restframework
here is my code
#api_view(['POST'])
#permission_classes([IsAuthenticated,])
def createOrderForOnlineClasses(request):
user = request.user
data = request.data
Class = OnlineClass.objects.get(id= data["classId"])
orderCred = {
'pin' : 'somepin',
'amount' : int(Class.totalPrice),
'callback' : 'http://localhost:3000/verify/',
}
for i in user.userprofile.onlineClass.all():
if i == Class:
return Response({"details": "allready registered"}, status=status.HTTP_400_BAD_REQUEST)
else:
try:
response = requests.post("URL_TO_SOMEWHERE", data=orderCred)
if response.status_code == 200 and not response.text.replace('-',"").isdigit():
registeredClass = RegisterStudentForOnlineClass.objects.create(
user=user,
totalPrice = int(Class.totalPrice),
transId = response.text,
onlineClassName= Class
)
serializer = RegisterForClassSerializer(registeredClass , many=False)
return Response(serializer.data)
else:
return Response({"details": ""} , status= status.HTTP_400_BAD_REQUEST)
except Exception as e:
return Response({"details": e})
here is the returned error
Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from the view, but received a `<class 'NoneType'>`
Thank you :)
when you call for i in user.userprofile.onlineClass.all() and it is empty it will simply pass the loop. Your problem is actually that you just need a default response for the scenario that user.userprofile.onlineClass.all() is empty.
Simply put a default expected response after the for loop

change boolean field to True after Payment?

I use stripe Api Payment method and I have a boolean filed in my database called ordered set to False
I just want it to be True after payment
Here is my views.py:
class OrderSummary(LoginRequiredMixin, View):
def post(self, request, *args, **kwargs):
order = Order.objects.get(user=self.request.user) #this is to bring the order
delivered = order.ordered
YOUR_DOMAIN = "http://127.0.0.1:8000"
checkout_session = stripe.checkout.Session.create(
payment_method_types=['card'],
metadata={
"order_id":order.id,
"order":order,
"delivered":delivered
},
mode='payment',
success_url=YOUR_DOMAIN + "/",
cancel_url=YOUR_DOMAIN + "/",
)
return JsonResponse({'id': checkout_session.id})
And here is after payment webhook views:
#csrf_exempt
def stripe_webhook(request):
payload = request.body
sig_header = request.META['HTTP_STRIPE_SIGNATURE']
event = None
try:
event = stripe.Webhook.construct_event(
payload, sig_header, endpoint_secret
)
except ValueError as e:
# Invalid payload
return HttpResponse(status=400)
except stripe.error.SignatureVerificationError as e:
# Invalid signature
return HttpResponse(status=400)
if event['type'] == 'checkout.session.completed': #this is to bring the order
session = event['data']['object']
customer_email = session["customer_details"]["email"]
orders =session["metadata"]["delivered"]
orders=True
orders.save()
print(session)
# Passed signature verification
return HttpResponse(status=200)
but I got this error
AttributeError: 'bool' object has no attribute 'save'
You are calling save on a variable which is not your model object.
Try:
Order= OrderSummary.Objects.get(id=id)
Order.Ordered=True
Order.save()
This is because you can not .save() a variable (orders here) , you must .save() the model, so you must retrieve the Order object and set its ordered to True and then .save() the Order object.

UnboundLocalError:local variabel 'socialhandle' referenced before assignment

I'm working on a django project and i'm trying to fetch data from the database, according to some primary key value. However when the object exists in the DB then everything is working fine but when it doesn't then django is raising:
UnboundLocalError: local variable 'socialhandle' referenced before assignment.
Here is my django view:
def profile(request, profile_id):
"""View for returning a unique profile"""
profile = get_object_or_404(UserProfile, pk=profile_id)
try:
socialhandle = SocialPlatform.objects.get(user_id=profile_id)
except socialhandle.DoesNotExist:
socialhandle = None
context = {
'profile' : profile,
'socialhandle' : socialhandle,
}
return render(request, 'profiles/profile.html', context)
You cannot access socialhandle.DoesNotExist in the except block because if the try does not interpret successfully, socialhandle would still be undefined.
Solution 1: Use Django's standard exception for this case:
from django.core.exceptions import ObjectDoesNotExist
...
try:
socialhandle = SocialPlatform.objects.get(user_id=profile_id)
except ObjectDoesNotExist:
socialhandle = None
Solution 2: Look at the answer of #JPG
The proper way of handling the DoesNotExist is,
try:
...
except SomeModel.DoesNotExist:
...
Where the SomeModel should be the model class, not the model "instance"
So,
use except SocialPlatform.DoesNotExist instead of except socialhandle.DoesNotExist
def profile(request, profile_id):
"""View for returning a unique profile"""
profile = get_object_or_404(UserProfile, pk=profile_id)
try:
socialhandle = SocialPlatform.objects.get(user_id=profile_id)
except SocialPlatform.DoesNotExist:
socialhandle = None
context = {
'profile' : profile,
'socialhandle' : socialhandle,
}
return render(request, 'profiles/profile.html', context)

return response in django rest-framework

I am writing an app in django rest-framework:
My views.py:
class tagList(generics.ListCreateAPIView,APIView):
model = tags
serializer_class = getAllTagsDetailSerializer
def get_queryset(self):
print "q1"
print self.request.QUERY_PARAMS.get('tag', None)
print self.request.user
print "q1"
if tags.objects.filter(tag='burger')!= None:
return tags.objects.filter(tag='burger')
else:
content = {'please move along': 'nothing to see here'}
return Response(content, status=status.HTTP_404_NOT_FOUND)
I want to return error status code if query returns None.
But the problem if i try to set Response it throws error:
Exception Type: TypeError
Exception Value:
object of type 'Response' has no len()
Exception Location: /usr/local/lib/python2.7/dist-packages/django/core/paginator.py in _get_count, line 53
Else if query result is Not None it is working.
How can i set status code on Django rest-framework.
The method is expected to return a QuerySet, not a Response object, my bet is that you should throw an Exception, either an APIException or an Http404.
Anyway your handling seems odd, I think you should just return the QuerySet and the framework will handle if the result is empty or not. The method should look like this:
def get_queryset(self):
return tags.objects.filter(tag='burger')
Can you try this
model = tags # Model name
serializer_class = getAllTagsDetailSerializer # Call serializer
def get_queryset(self):
key = self.request.QUERY_PARAMS.get('appKey', None)
getTagName = self.request.QUERY_PARAMS.get('tagName')
keyData = app.objects.filter(appKey=key).exists()
try:
if keyData == True:
return tags.objects.filter(tag=getTagName)
else:
raise exceptions.PermissionDenied
except app.DoesNotExist:
pass
I think it will work....

How can I retrieve the email address from a Google Account and store it in my app's user profile when my user logs in using gae-simpleauth?

I'm attempting to build a very simple user permissions system with webapp2's auth library. I'm using gae-simpleauth to log users in with their Google account. I'm hoping to compare the user's email address to a list of permitted email addresses to determine if a user has access to a resource, but I'm not clear on how to get the email address from the Google account into the account on my app. Users are currently able to log in, but the email address doesn't seem to be something simpleauth adds to their account by default.
How can I retrieve the email address from Google and store it in my app's user profile using gae-simpleauth?
My implementation of gae-simpleauth is nearly identical to the example with the addition of the get_user_and_flags function which fetches the logged in user and sets the admin flag if the user's email is in a list in secrets.py. Unfortunately, that doesn't work because user doesn't have an email attribute.
# -*- coding: utf-8 -*-
import logging, secrets, webapp2
from google.appengine.api import users
from webapp2_extras import auth, sessions, jinja2
from jinja2.runtime import TemplateNotFound
from lib.simpleauth import SimpleAuthHandler
def get_user_and_flags(self):
"""Returns the current user and permission flags for that user"""
flags = {}
user = None
if self.logged_in:
user = self.current_user
flags = {
'admin': user.email in secrets.ADMIN_USERS,
}
return user, flags
def simpleauth_login_required(handler_method):
"""A decorator to require that a user be logged in to access a handler.
To use it, decorate your get() method like this:
#simpleauth_login_required
def get(self):
user = self.current_user
self.response.out.write('Hello, ' + user.name())
"""
def check_login(self, *args, **kwargs):
if self.request.method != 'GET':
self.abort(400, detail='The login_required decorator '
'can only be used for GET requests.')
if self.logged_in:
handler_method(self, *args, **kwargs)
else:
self.session['original_url'] = self.request.url.encode('ascii', 'ignore')
self.redirect('/login/')
return check_login
class BaseRequestHandler(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 jinja2(self):
"""Returns a Jinja2 renderer cached in the app registry"""
return jinja2.get_jinja2(app=self.app)
#webapp2.cached_property
def session(self):
"""Returns a session using the default cookie key"""
return self.session_store.get_session()
#webapp2.cached_property
def auth(self):
return auth.get_auth()
#webapp2.cached_property
def current_user(self):
"""Returns currently logged in user"""
user_dict = self.auth.get_user_by_session()
return self.auth.store.user_model.get_by_id(user_dict['user_id'])
#webapp2.cached_property
def logged_in(self):
"""Returns true if a user is currently logged in, false otherwise"""
return self.auth.get_user_by_session() is not None
def render(self, template_name, template_vars={}):
# Preset values for the template
values = {
'url_for': self.uri_for,
'logged_in': self.logged_in,
'flashes': self.session.get_flashes()
}
# Add manually supplied template values
values.update(template_vars)
# read the template or 404.html
try:
self.response.write(self.jinja2.render_template(template_name, **values))
except TemplateNotFound:
self.abort(404)
def head(self, *args):
"""Head is used by Twitter. If not there the tweet button shows 0"""
pass
class ProfileHandler(BaseRequestHandler):
def get(self):
"""Handles GET /profile"""
if self.logged_in:
self.render('profile.html', {
'user': self.current_user,
'session': self.auth.get_user_by_session()
})
else:
self.redirect('/')
class AuthHandler(BaseRequestHandler, SimpleAuthHandler):
"""Authentication handler for OAuth 2.0, 1.0(a) and OpenID."""
# Enable optional OAuth 2.0 CSRF guard
OAUTH2_CSRF_STATE = True
USER_ATTRS = {
'facebook' : {
'id' : lambda id: ('avatar_url',
'http://graph.facebook.com/{0}/picture?type=large'.format(id)),
'name' : 'name',
'link' : 'link'
},
'google' : {
'picture': 'avatar_url',
'name' : 'name',
'link' : 'link'
},
'windows_live': {
'avatar_url': 'avatar_url',
'name' : 'name',
'link' : 'link'
},
'twitter' : {
'profile_image_url': 'avatar_url',
'screen_name' : 'name',
'link' : 'link'
},
'linkedin' : {
'picture-url' : 'avatar_url',
'first-name' : 'name',
'public-profile-url': 'link'
},
'foursquare' : {
'photo' : lambda photo: ('avatar_url', photo.get('prefix') + '100x100' + photo.get('suffix')),
'firstName': 'firstName',
'lastName' : 'lastName',
'contact' : lambda contact: ('email',contact.get('email')),
'id' : lambda id: ('link', 'http://foursquare.com/user/{0}'.format(id))
},
'openid' : {
'id' : lambda id: ('avatar_url', '/img/missing-avatar.png'),
'nickname': 'name',
'email' : 'link'
}
}
def _on_signin(self, data, auth_info, provider):
"""Callback whenever a new or existing user is logging in.
data is a user info dictionary.
auth_info contains access token or oauth token and secret.
"""
auth_id = '%s:%s' % (provider, data['id'])
logging.info('Looking for a user with id %s', auth_id)
user = self.auth.store.user_model.get_by_auth_id(auth_id)
_attrs = self._to_user_model_attrs(data, self.USER_ATTRS[provider])
if user:
logging.info('Found existing user to log in')
# Existing users might've changed their profile data so we update our
# local model anyway. This might result in quite inefficient usage
# of the Datastore, but we do this anyway for demo purposes.
#
# In a real app you could compare _attrs with user's properties fetched
# from the datastore and update local user in case something's changed.
user.populate(**_attrs)
user.put()
self.auth.set_session(
self.auth.store.user_to_dict(user))
else:
# check whether there's a user currently logged in
# then, create a new user if nobody's signed in,
# otherwise add this auth_id to currently logged in user.
if self.logged_in:
logging.info('Updating currently logged in user')
u = self.current_user
u.populate(**_attrs)
# The following will also do u.put(). Though, in a real app
# you might want to check the result, which is
# (boolean, info) tuple where boolean == True indicates success
# See webapp2_extras.appengine.auth.models.User for details.
u.add_auth_id(auth_id)
else:
logging.info('Creating a brand new user')
ok, user = self.auth.store.user_model.create_user(auth_id, **_attrs)
if ok:
self.auth.set_session(self.auth.store.user_to_dict(user))
# Remember auth data during redirect, just for this demo. You wouldn't
# normally do this.
self.session.add_flash(data, 'data - from _on_signin(...)')
self.session.add_flash(auth_info, 'auth_info - from _on_signin(...)')
# Go to the last page viewed
target = str(self.session['original_url'])
self.redirect(target)
def logout(self):
self.auth.unset_session()
self.redirect('/')
def handle_exception(self, exception, debug):
logging.error(exception)
self.render('error.html', {'exception': exception})
def _callback_uri_for(self, provider):
return self.uri_for('auth_callback', provider=provider, _full=True)
def _get_consumer_info_for(self, provider):
"""Returns a tuple (key, secret) for auth init requests."""
return secrets.AUTH_CONFIG[provider]
def _to_user_model_attrs(self, data, attrs_map):
"""Get the needed information from the provider dataset."""
user_attrs = {}
for k, v in attrs_map.iteritems():
attr = (v, data.get(k)) if isinstance(v, str) else v(data.get(k))
user_attrs.setdefault(*attr)
return user_attrs
Hope this help( I have same probblem )
First change in secrets.py in line:
'google': (GOOGLE_APP_ID, GOOGLE_APP_SECRET, 'https://www.googleapis.com/auth/userinfo.profile'),
to
'google': (GOOGLE_APP_ID,GOOGLE_APP_SECRET, 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email'),
and in auth.py change USER_ATTRS =
{
...
'google' : {
'picture': 'avatar_url',
'email' : 'email', <-- new attr
'name' : 'name',
'link' : 'link'
},
}
Since your question includes no code snippet, I can only guess at what you have done so far. In light of that, the below code should work:
from google.appengine.api import users
user = users.get_current_user()
email = user.email()
Following the idea of nguyên, I add customize also the "_to_user_model_attrs" method.
Here my piece of code:
def _to_user_model_attrs(self, data, attrs_map):
"""Get the needed information from the provider dataset."""
user_attrs = {}
for k, v in attrs_map.iteritems():
if v =="email":
attr = (v, data.get(k)[0].get('value'))
else:
attr = (v, data.get(k)) if isinstance(v, str) else v(data.get(k))
user_attrs.setdefault(*attr)
return user_attrs
It works for me!
There seem to be several methods of authentication, and mix-matching does not work. If you havne't already, make sure you read through this, https://developers.google.com/appengine/articles/auth
There are a few sections that might be relative depending on what else you have been doing with Google.
Changes from the Google Apps account transition
Configuring Google Apps to Authenticate on Appspot

Categories

Resources