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.
Related
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
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):
...
I wrote a captcha decorator...
def validate_captcha(view):
'''Decorator to validate a captcha based on settings'''
def failure():
return HttpResponse('There was an error, please refresh and try again')
def wrap(request, *args, **kwargs):
if request.method == 'POST':
url = "https://www.google.com/recaptcha/api/siteverify"
values = {
'secret': settings.GOOGLE_RECAPTCHA_SECRET_KEY,
'response': request.POST.get(u'g-recaptcha-response', None),
'remoteip': request.META.get("REMOTE_ADDR", None),
}
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
result = json.loads(response.read())
# result["success"] will be True on a success
if result["success"]:
return view
else:
return failure
return failure
return wrap
and then used it on a view...
#validate_captcha
def sendemail(request):
...
but then I get an attribute error...
Traceback:
File "/home/jeff/Django/langalang/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
223. response = middleware_method(request, response)
File "/home/jeff/Django/langalang/venv/local/lib/python2.7/site-packages/django/middleware/common.py" in process_response
138. if response.status_code == 404 and not settings.DEBUG:
Exception Type: AttributeError at /ko/contact/sendemail
Exception Value: 'function' object has no attribute 'status_code'
I THINK...this is happening because it returned a function, but I cannot figure out why django is treating this as a response, because the response was already handled in my decorator and I verified that it made it through to the return point 'result["success"]'
I think you should call the failure() function so that you actually have an HttpResponse returned from the wrapping decorator. Replace:
return failure
with:
return failure()
And, the same goes for the view, call it:
return view(request, *args, **kwargs)
I am doing migration on a django site, I rewrote the list_object view to class based view which inheritated from django.views.generic.ListView, but I got error when I create get_context_data method
My code here:
class ForumView(ListView):
context_object_name = 'forum'
template_name = 'forum/thread_list.html',
paginate_by = FORUM_PAGINATION
def get_queryset(self):
try:
f = Forum.objects.for_groups(self.request.user.groups.all()).select_related().get(slug=self.kwargs['slug'])
except Forum.DoesNotExist:
raise Http404
return f.thread_set.select_related().all()
def get_context_data(self, **kwargs):
try:
f = Forum.objects.for_groups(self.request.user.groups.all()).select_related().get(slug=self.kwargs['slug'])
except Forum.DoesNotExist:
raise Http404
form = CreateThreadForm()
child_forums = f.child.for_groups(self.request.user.groups.all())
extra_context = {
'forum': f,
'child_forums': child_forums,
'form': form,
'login': {
'reason': _('create a new thread'),
'next': f.get_absolute_url(),
},
'section': 'forum',
}
context = super(ForumView, self).get_context_data(**kwargs)
for key in extra_context:
context[key] = extra_context[key]
return context
and url.py
url(r'^thread/(?P<thread>[0-9]+)/$', ThreadView.as_view(), name='forum_view_thread'),
but the django return a debug page with:
Exception Value: get_context_data() keywords must be strings
Python Version: 2.7.3
Django Version: 1.5.2
Request URL: http://localhost:8000/forum/thread/1/
Exception Location: /Library/Python/2.7/site-packages/django/views/generic/list.py in get_context_data, line 116
traceback:
/Library/Python/2.7/site-packages/django/core/handlers/base.py in get_response
response = callback(request, *callback_args, **callback_kwargs) ...
/Library/Python/2.7/site-packages/django/views/generic/base.py in view
return self.dispatch(request, *args, **kwargs) ...
/Library/Python/2.7/site-packages/django/views/generic/base.py in dispatch
return handler(request, *args, **kwargs) ...
/Library/Python/2.7/site-packages/django/views/generic/list.py in get
context = self.get_context_data(object_list=self.object_list) ...
/Users/foulwall/Dropbox/mldata/forum/views.py in get_context_data
context = super(ThreadView, self).get_context_data(**kwargs) ...
/Library/Python/2.7/site-packages/django/views/generic/list.py in get_context_data
return super(MultipleObjectMixin, self).get_context_data(**context) ...
Anyone with a solution? thanks~
I suspect that one of the kwargs that you are sending to get_context_data is not a simple string object. This could be passed through as the key in a kwargs dictionary. Perhaps it is a lazy or a translatable string?
Something similar happened to the person that asked this question. If it the same issue, I suggest you ensure that the variable name is indeed a simple string. Unicode chars in variable names are odd, but acceptable btw.
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....