'method' object is not subscriptable trying for google api books - python

Trying to get data from google books API but it is showing the error ' 'method' object is not subscriptable'
I know the “TypeError: ‘method’ object is not subscriptable” error is raised when you use square brackets to call a method inside a class. To solve this error, make sure that you only call methods of a class using round brackets after the name of the method you want to call.
def books(request):
if request.method == "POST":
form = DashboardForm(request.POST)
text = request.POST['text']
url = 'https://www.googleapis.com/books/v1/volumes?q='+text
r = requests.get(url)
answer = r.json
result = []
for i in range(10):
result_dict= {
'title':answer['items'][i]['volumeInfo']['title'], # This line is showing error.
'subtitle': answer['items'][i]['volumeInfo']['title'].get('subtitle'),
'description': answer['items'][i]['volumeInfo']['title'].get('description'),
'count': answer['items'][i]['volumeInfo']['title'].get('pageCount'),
'categories': answer['items'][i]['volumeInfo']['title'].get('categories'),
'rating': answer['items'][i]['volumeInfo']['title'].get('pageRating'),
'thumbnail': answer['items'][i]['volumeInfo']['title'].get('imageLinks'),
'preview': answer['items'][i]['volumeInfo']['title'].get('previewLink')
}
result.append(result_dict)
context={
'form':form,
'results':result,
}
return render(request,'dashboard/books.html',context)
else:
form = DashboardForm()
context = {'form':form}
return render(request,'dashboard/books.html',context)

In line 7, you write:
answer = r.json
But r.json is a method which you should call:
answer = r.json()

Related

HackerNews API extraction error - TypeError: list indices must be integers or slices, not str

Trying to run this code to get the topstories from hacker news is giving me this error 'TypeError: list indices must be integers or slices, not str', the error is generated at
story = data['story']
from multiprocessing import context
from django.shortcuts import render
import requests
# Create your views here.
def index(request):
#make an api call and save response
url = f'https://hacker-news.firebaseio.com/v0/topstories.json'
response = requests.get(url)
data = response.json()
story = data['story']
context = {
'story': story
}
return render(request, 'SyncNews/index.html', context)
What can I do to correct this error as I'm following a video showing a similar project but this error was not seen, I've also tried removing the '' but receive an error 'UnboundLocalError at /
local variable 'story' referenced before assignment'
story = data['story']
Your 'data' is a list of numbers, not a dictionary. Depending on whether you want to have one or more numbers from that list you can do one of such options:
# first number:
def index(request):
...
data = response.json()
story = data[0]
context = {
'story': story
}
return render(request, 'SyncNews/index.html', context)
# list of numbers:
def index(request):
...
data = response.json()
context = {
'story': data
}
return render(request, 'SyncNews/index.html', context)

How can I solve the Not found problem when getting from pytest-django through pk?

I have a problem with django-pytest
I'm using, djnago-rest-framework
There is a problem testing the details. As shown in the code below, I entered the same details, detail1, detail2, and detail3 codes. However, only detail1 succeeds and detail2, detail3 indicates that '/api/v1/stats/1/' could not be found. It also occurs when implementing delete. I am curious about the cause and solution of this error.
enter image description here
// tests/test_apis.py
import json
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APITestCase
from stats.models import Stats
class StatsApiTests(APITestCase):
def setUp(self):
Stats.objects.get_or_create(blockshots=1, memo='test1')
Stats.objects.get_or_create(blockshots=2, memo='test2')
self.create_read_url = reverse('api:stats:stats-list')
self.read_update_delete_url = reverse('api:stats:stats-detail', kwargs={'pk': '1'})
def test_detail1(self):
response = self.client.get(self.read_update_delete_url)
data = json.loads(response.content)
content = {
'blockshots': 1,
'memo': 'test1',
}
self.assertEqual(data, content)
def test_detail2(self):
response = self.client.get(self.read_update_delete_url)
data = json.loads(response.content)
content = {
'blockshots': 1,
'memo': 'test1',
}
self.assertEqual(data, content)
def test_detail3(self):
response = self.client.get(self.read_update_delete_url)
data = json.loads(response.content)
content = {
'blockshots': 1,
'memo': 'test1',
}
self.assertEqual(data, content)
def test_list(self):
response = self.client.get(self.create_read_url)
self.assertContains(response, 'test1')
self.assertContains(response, 'test2')
Its hard to know what your actual implementation for read_update_delete_url, hence I assume it is looking up the resource by primary key. In that case, you can simply add the primary key in the url like this:
stat_one, _ = Stats.objects.get_or_create(blockshots=1, memo='test1')
stat_two, _ = Stats.objects.get_or_create(blockshots=2, memo='test2')
self.read_update_delete_url = reverse('api:stats:stats-detail', kwargs={'pk': stat_one.pk})
Basically, get_or_create returns the object and the state of the object (created or not). You can use the object's id as the parameter of reverse function.

AttributeError: 'NoneType' object has no attribute 'get' even though I have an instance of the class I'm using

When I run my test, which is the following:
def test_match_data_while_updating(self):
match_updated_data = {
'id': 1,
'status': 'not_started',
}
match = Match.objects.first()
# TST N.1 : status not_started
# -------
match.status = 'not_started'
request = self.__class__.factory.put('', match_updated_data, format='json')
add_authentication_to_request(request, is_staff=True)
response = update_match_video(request)
self.assertEqual(Match.objects.first().status,'live')
I get the Error that says:
print('request data get match: ',request.data.get('match').get('id'))
AttributeError: 'NoneType' object has no attribute 'get'
Here is the function I'm testing:
def update_match_video(request):
print('request data get match: ',request.data.get('match').get('id'))
if not request.data.get('match').get('id'):
return JsonResponse({}, status=status.HTTP_400_BAD_REQUEST)
try:
match_id = valid_data_or_error(request.data, method='PUT')['match_data']['id']
match = Match.objects.get(id = match_id)
db_match_status = match.status
if db_match_status == 'live':
valid_data_or_error(request.data, method='PUT')['match_data']['status'] = 'live'
else:
if db_match_status == 'closed':
valid_data_or_error(request.data, method='PUT')['match_data']['status'] = 'closed'
except Match.DoesNotExist:
print('Match does not exist')
I will appreciate some help please!
Well, request.data is None:
One way to be certain to hit a function that takes a request argument is to use Django's test client and be certain to PT the value that you are expecting:
from django.test import Client
from django.test import TestCase
... other import as needed
class TestMyFunc(TestCase):
def setUp(self):
self.client = Client()
def test_match_data_while_updating(self):
match_updated_data = {
'id': 1,
'status': 'not_started',
}
match = Match.objects.first()
# TST N.1 : status not_started
# -------
match.status = 'not_started'
response = self.client.put( .... ) ## JSON of put data -- make certain to PUT "{ .., match: "something!", ..}
self.assertEqual(response.status_code, 200)
... other assertions
Now, this creates a test database (and ought to have no side effects (unit test, not integration test)) and can be repeated reliably.
To get django to run this test put it in a directory called tests under the main project directory (adjacent to views, models, etc) and do python manage.py run tests
Hope that helps

Error 500 when retrieving empty GET parameter

My code looks like this :
def rssfeeds(request):
reqdata = request.GET['url']
if reqdata == '':
d = "https://github.com/rudrasingh99.private.atom?token=MYPRIVATETOKEN"
data = []
for post in d.entries:
data.append(post.title)
my_context = {
"my_list" : data,
}
else:
d = feedparser.parse(reqdata)
data = []
for post in d.entries:
data.append(post.title)
my_context = {
"my_list" : data,
}
return render(request,"base.html",my_context)
def home_view(request):
return render(request,"index.html",{})
while whenever i try with empty url parameter it gives me 500 error.
Thanks in advance
It gives you a 500 error because the request.GET is a dictionary. It's really a KeyError under the hood; set DEBUG=True to find this.
Use .get to get terms with default values and handle appropriately.
reqdata = request.GET.get('url', 'mydefaultvalue')
If url is required for the page to load properly, maybe consider returning a human readable error?
reqdata = request.GET.get('url', '')
if reqdata == '':
return HttpResponse("Specify a url!")

Django sending data to front-end. 'dict' object has no attribute '_meta'

I have these methods:
def get_all_from_database():
urls = Url.objects.all()
ips = Ip.objects.all()
context = {
'urls': serializers.serialize('json', urls),
'ip': serializers.serialize('json', ips)
}
return context
and the method that sends data to using ajax:
def send_results(request):
if request.is_ajax():
address = request.POST.get('url')
process_data(address, email_to, email_from)
context = get_all_from_database()
return HttpResponse(json.dumps(context), content_type='application/json')
But this raises error : INTERNAL SERVER ERROR 500 'dict' object has no attribute '_meta'.
Wheres the mistake, and how to correct it ?
You cant use serializers.serialize method with dict list that you got from values call:
urls = Url.objects.all().values('address', 'cnt')
Use default queryset:
urls = Url.objects.all()
ips = Ip.objects.all()
In you example context['urls'] value already in json format, and you cant use json.dumps() for json data.
You can use this example:
json.dumps({
'urls': Urls.objects.all().values_list('address', 'cnt'),
'ips': Ip.objects.all().values_list('address', 'cnt')
}), 'json')
urls = Url.objects.all().values('address', 'cnt')
ips = Ip.objects.all().values('address', 'cnt')
The above lines returns dict objects, try:
urls = Url.objects.all().values('address', 'cnt').values_list()
ips = Ip.objects.all().values('address', 'cnt').values_list()
Then you will have urls as a list containing the tuples:
[(address_1, cnt_1), (address_2, cnt_2), ...]
see: QuerySet API reference
I think it should be :
res=json.dumps({
'urls': list(Urls.objects.all().values_list('address', 'cnt')),
'ips': list(Ip.objects.all().values_list('address', 'cnt'))
}), 'json')
return HttpResponse(res,content_type="application/json")

Categories