return response in django rest-framework - python

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....

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.

How do i get the context to test my view page?

I'm trying to test my search results to check the response when there are no results.
this is the function in my view:
def get_context_data(self, *args, **kwargs):
result = super().get_context_data(**kwargs)
query = self.request.GET.get('q')
result['book'] = get_object_or_404(books,ISBN = query)
return result
this is my test class and function
class Test_Search_results_view(TestCase):
def test_no_results(self):
response1 = self.client.get('/TextSearch/results1/?books=new&q=9780815345244')
response2 = self.client.get('/TextSearch/results2/?books=new&author=Bruce+Alberts&Book+Name=Molecular+Biology+of+the+Cell&edition=6')
self.assertEqual(response1.status_code, 404)
self.assertEqual(response2.status_code, 404)
self.assertQuerysetEqual(response2.context['book'],[])
but i keep getting this error
self.assertQuerysetEqual(response2.context['book'],[])
File "C:----\context.py", line 83, in __getitem__
raise KeyError(key)
KeyError: 'book'
how do I check if my book query got empty results?
If this line: result['book'] = get_object_or_404(books,ISBN = query) causes 404 to be raised, then, you will have nothing in result['book']. Because the 404 is and exception which is raised. get_object_or_404 does not return an empty value which you could assert in your test.

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)

Django - error_403() got an unexpected keyword argument 'exception'

When the user is not allowed to see the contents of the instance, when the PermissionDenied exception was thrown, instead of forwarding it to the 404.html template, it has an error.
DetailView:
class OccurrenceDetail(OccurrenceModel, BaseDetailViewWithLogin):
permission_required = ('occurrences.see_occurrence')
def get_object(self, queryset=None):
perm = self.request.user.has_perm(self.permission_required)
obj = super(OccurrenceDetail, self).get_object(queryset=queryset)
if not perm:
raise PermissionDenied()
return obj
Urls:
handler403 = 'apps_core.core.views.error_403'
Views:
def error_403(request):
data = {}
return render(request,'errors/403.html', data)
The 403 error view expects a second argument, which is the raised exception.
To solve it, you can change your code to:
def error_403(request, exception):
...
or something more general
def error_403(request, *args, **kwargs):
...

Categories

Resources