Getting error with simple select statement on web2py's 'image blog' - python

For my project, I need to connect to multiple databases and get information from them. I didn't think this would be a problem with web2py, but it was. I thought maybe I need to rebuild the db from scratch, but still had problems. Finally, I went through the introductory 'images' tutorial and changed it to use an alternate mysql database. I still got the same errors, below is the code:
db.py
db = DAL("mysql://root:#localhost/web2py")
images_db = DAL("mysql://root:#localhost/images_test")
images_db.define_table('image',
Field('title', unique=True),
Field('file', 'upload'),
format = '%(title)s')
images_db.define_table('comment',
Field('image_id', images_db.image),
Field('author'),
Field('email'),
Field('body', 'text'))
Then I went to the admin page for 'images' and clicked the 'shell' link under 'controllers' and did the following: (after I went to the index page to generate the 'images':
Shell:
In [1] : print db(images_db.image).select()
Traceback (most recent call last):
File "/home/cody/Downloads/web2py/gluon/contrib/shell.py", line 233, in run
exec compiled in statement_module.__dict__
File "<string>", line 1, in <module>
File "/home/cody/Downloads/web2py/gluon/dal.py", line 7577, in select
fields = adapter.expand_all(fields, adapter.tables(self.query))
File "/home/cody/Downloads/web2py/gluon/dal.py", line 1172, in expand_all
for field in self.db[table]:
File "/home/cody/Downloads/web2py/gluon/dal.py", line 6337, in __getitem__
return dict.__getitem__(self, str(key))
KeyError: 'image'
In [2] : print images_db.has_key('image')
True
In [3] : print images_db
<DAL {'_migrate_enabled': True, '_lastsql': "SET sql_mode='NO_BACKSLASH_ESCAPES';", '_db_codec': 'UTF-8', '_timings': [('SET FOREIGN_KEY_CHECKS=1;', 0.00017380714416503906), ("SET sql_mode='NO_BACKSLASH_ESCAPES';", 0.00016808509826660156)], '_fake_migrate': False, '_dbname': 'mysql', '_request_tenant': 'request_tenant', '_adapter': <gluon.dal.MySQLAdapter object at 0x2b84750>, '_tables': ['image', 'comment'], '_pending_references': {}, '_fake_migrate_all': False, 'check_reserved': None, '_uri': 'mysql://root:#localhost/images_test', 'comment': <Table {'body': <gluon.dal.Field object at 0x2b844d0>, 'ALL': <gluon.dal.SQLALL object at 0x2b84090>, '_fields': ['id', 'image_id', 'author', 'email', 'body'], '_sequence_name': 'comment_sequence', '_plural': 'Comments', 'author': <gluon.dal.Field object at 0x2b84e10>, '_referenced_by': [], '_format': None, '_db': <DAL {...}>, '_dbt': 'applications/images/databases/e1e448013737cddc822e303fe20f8bec_comment.table', 'email': <gluon.dal.Field object at 0x2b84490>, '_trigger_name': 'comment_sequence', 'image_id': <gluon.dal.Field object at 0x2b84050>, '_actual': True, '_singular': 'Comment', '_tablename': 'comment', '_common_filter': None, 'virtualfields': [], '_id': <gluon.dal.Field object at 0x2b84110>, 'id': <gluon.dal.Field object at 0x2b84110>, '_loggername': 'applications/images/databases/sql.log'}>, 'image': <Table {'ALL': <gluon.dal.SQLALL object at 0x2b84850>, '_fields': ['id', 'title', 'file'], '_sequence_name': 'image_sequence', 'file': <gluon.dal.Field object at 0x2b847d0>, '_plural': 'Images', 'title': <gluon.dal.Field object at 0x2b84610>, '_referenced_by': [('comment', 'image_id')], '_format': '%(title)s', '_db': <DAL {...}>, '_dbt': 'applications/images/databases/e1e448013737cddc822e303fe20f8bec_image.table', '_trigger_name': 'image_sequence', '_loggername': 'applications/images/databases/sql.log', '_actual': True, '_tablename': 'image', '_common_filter': None, 'virtualfields': [], '_id': <gluon.dal.Field object at 0x2b848d0>, 'id': <gluon.dal.Field object at 0x2b848d0>, '_singular': 'Image'}>, '_referee_name': '%(table)s', '_migrate': True, '_pool_size': 0, '_common_fields': [], '_uri_hash': 'e1e448013737cddc822e303fe20f8bec'}>
Now I don't quite understand why I am getting errors here, everything appears to be in order. I thought web2py supported multiple databases? Am I doing it wrong? The appadmin works fine, perhaps I'll edit it and get it to raise an error with the code it's generating... any help would be appreciated.
Cody
UPDATE:
I just tried this:
MODELS/DB.PY
db = DAL("mysql://root:#localhost/web2py")
images_db = DAL("mysql://root:#localhost/images_test")
images_db.define_table('image',
Field('title', unique=True),
Field('file', 'upload'),
format = '%(title)s')
images_db.define_table('comment',
Field('image_id', images_db.image),
Field('author'),
Field('email'),
Field('body', 'text'))
CONTROLLERS/DEFAULT.PY
def index():
"""
example action using the internationalization operator T and flash
rendered by views/default/index.html or views/generic.html
"""
if images_db.has_key('image'):
rows = db(images_db.image).select()
else:
rows = 'nope'
#rows = dir(images_db)
return dict(rows=rows)
VIEWS/DEFAULT/INDEX.HTML
{{left_sidebar_enabled,right_sidebar_enabled=False,True}}
{{extend 'layout.html'}}
these are the rows:
{{=rows }}
Again, very confused by all of this. Appreciate any help.

If you want to query the images_db connection, you have to call images_db(), not db(). So, it would be:
images_db(images_db.image).select()

Related

Django: How to search through django.template.context.RequestContext

I'm working over tests in Django and faced <class 'django.template.context.RequestContext'>, which I'm trying to iterate through and find <class 'ecom.models.Product'> object inside.
test.py
def test_ProductDetail_object_in_context(self):
response = self.client.get(reverse('product_detail', args=[1]))
# assertEqual - test passes
self.assertEqual(response.context[0]['object'], Product.objects.get(id=1))
# assertIn - test fails
self.assertIn(Product.objects.get(id=1), response.context[0])
views.py
class ProductDetailView(DetailView):
model = Product
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
data = cartData(self.request)
cartItems = data['cartItems']
context['cartItems'] = cartItems
return context
What's inside response.context:
[
[
{'True': True, 'False': False, 'None': None},
{'csrf_token': <SimpleLazyObject: <function csrf.<locals>._get_val at 0x7fd80>>,
'request': <WSGIRequest: GET '/1/'>,
'user': <SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x7fd820>>, '
perms': <django.contrib.auth.context_processors.PermWrapper object at 0x7fd80>,
'messages': <django.contrib.messages.storage.fallback.FallbackStorage object at 0x7fd8290>,
'DEFAULT_MESSAGE_LEVELS': {'DEBUG': 10, 'INFO': 20, 'SUCCESS': 25, 'WARNING': 30, 'ERROR': 40}
},
{},
{'object': <Product: Pen>,
'product': <Product: Pen>,
'view': <ecom.views.ProductDetailView object at 0x7fd8210>,
'cartItems': 0}
],
[
{'True': True, 'False': False, 'None': None},
{'csrf_token': <SimpleLazyObject: <function csrf.<locals>._get_val at 0x7fd8240>>,
'request': <WSGIRequest: GET '/1/'>,
'user': <SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x7fd8250>>,
'perms': <django.contrib.auth.context_processors.PermWrapper object at 0x7fd8250>,
'messages': <django.contrib.messages.storage.fallback.FallbackStorage object at 0x7fd8290>,
'DEFAULT_MESSAGE_LEVELS': {'DEBUG': 10, 'INFO': 20, 'SUCCESS': 25, 'WARNING': 30, 'ERROR': 40}
},
{},
{'object': <Product: Pen>,
'product': <Product: Pen>,
'view': <ecom.views.ProductDetailView object at 0x7fd8210>,
'cartItems': 0}
]
]
Type of response.context:
<class 'django.template.context.RequestContext'>
What's inside Product.objects.get(id=1) is: Pen
Type of Product.objects.get(id=1) is: <class 'ecom.models.Product'>
I don't undestand why:
it found Product object in self.assertEqual(response.context[0]['object'], Product.objects.get(id=1)), but not in self.assertIn(Product.objects.get(id=1), response.context[0]['object']) - says TypeError: argument of type 'Product' is not iterable
it also didn't find it in self.assertIn(Product.objects.get(id=1), response.context[0]) - says "AssertionError: <Product: Pen> not found in [....here goes contents of response.context[0]....]"
it also didn't find it in self.assertIn(Product.objects.get(id=1), response.context[0][3]) - says "in getitem raise KeyError(key), KeyError: 3"
how to work with RequestContext class? JSON like?
Sorry for a bit mixed up question, just trying to understand how to work with RequestContext.
Thank you in advance!
I think your test is failing because assertIn looks through the KEYS not the values. Solution would be:
self.assertIn(Product.objects.get(id=1), response.context[0].values())
A little more explanation: response.context[0] seems like it's some key-value storage, i.e. a dict. When you do response.context[0]["object"], you've just accessed the value at the key "object" where response.context[0] is the dict. Doing some in query on the dictionary only looks up the keys of the dictionary.

How to correctly serialize API response in Django view

I am calling the Giphy API using another wrapper API which returns a list of dictionaries. I am having hard times to serialize the data to return it to AJAX.
The data is returned as InlineResponse200 with three properties.
(docu)
The problem is that my view is not able to return the JSON properly:
# Traceback
[2020-06-23 14:58:54,086] log: ERROR - Internal Server Error: /get_gifs/
Traceback (most recent call last):
File "C:\Users\Jonas\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\Jonas\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Jonas\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Jonas\Desktop\finsphere\finsphere\blog\views.py", line 234, in get_gifs
return JsonResponse(api_response.data[0])
File "C:\Users\Jonas\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\http\response.py", line 554, in __init__
raise TypeError(
TypeError: In order to allow non-dict objects to be serialized set the safe parameter to False.
[23/Jun/2020 14:58:54] "POST /get_gifs/ HTTP/1.1" 500 17874
If I add safe=False it returns TypeError: Object of type Gif is not JSON serializable
I don't get this since api_response.data[0] is a cristal clear dictionary.
Desired outcome: Get the Giphy object logged in the success function of Ajax.
AJAX
(function($) {
$('#btnSearch').on('click', function(e) {
var query = $('#search').val();
console.log(query);
e.preventDefault();
$.ajax({
type: 'post',
async: true,
url: '/get_gifs/',
data: {
'query': query,
'csrfmiddlewaretoken': window.CSRF_TOKEN // from blog.html
},
success: function(response) {
},
error: function(xhr, status, error) {
// shit happens friends!
}
});
});
}(jQuery));
(Inserted my original -free- API key for reproduction)
Views.py
def get_gifs(request):
# create an instance of the API class
api_instance = giphy_client.DefaultApi()
# API Key
api_key = 'NGSKWrBqtIq1rFU1Ka11D879Y1u4Igia'
# Search term
q = request.POST.get('query')
print(q)
# Query parameters
limit = 2
offset = 0
rating = 'g'
lang = 'en'
fmt = 'json'
try:
# Search Endpoint
api_response = api_instance.gifs_search_get(api_key, q, limit=limit, offset=offset, rating=rating, lang=lang, fmt=fmt)
pprint(api_response)
except ApiException as e:
print("Exception when calling DefaultApi->gifs_search_get: %s\n" % e)
return JsonResponse(api_response.data[0])
API fetched object (pprint api_response)
{'data': [{'bitly_gif_url': 'https://gph.is/g/EJWjdvN',
'bitly_url': 'https://gph.is/g/EJWjdvN',
'content_url': '',
'create_datetime': None,
'embed_url': 'https://giphy.com/embed/J0JGg6doLfmV0yZmIB',
'featured_tags': None,
'id': 'J0JGg6doLfmV0yZmIB',
'images': {'downsized': {'height': '250',
'size': '350582',
'url': 'https://media3.giphy.com/media/J0JGg6doLfmV0yZmIB/giphy.gif?cid=ecefd82565bc1664c2b17e3e4b60d88c736d0c6b5a39d682&rid=giphy.gif',
'width': '478'},
'downsized_large': {'height': '250',
'size': '350582',
'url': 'https://media3.giphy.com/media/J0JGg6doLfmV0yZmIB/giphy.gif?cid=ecefd82565bc1664c2b17e3e4b60d88c736d0c6b5a39d682&rid=giphy.gif',
'width': '478'},
'preview_gif': {'height': '134',
'size': '49623',
'url': 'https://media3.giphy.com/media/J0JGg6doLfmV0yZmIB/giphy-preview.gif?cid=ecefd82565bc1664c2b17e3e4b60d88c736d0c6b5a39d682&rid=giphy-preview.gif',
'width': '256'}},
'import_datetime': '2020-06-15 10:01:39',
'is_anonymous': None,
'is_community': None,
'is_featured': None,
'is_hidden': None,
'is_indexable': None,
'is_realtime': None,
'is_removed': None,
'is_sticker': False,
'rating': 'g',
'slug': 'MITEF-mitefarab-asc2020-J0JGg6doLfmV0yZmIB',
'source': 'www.mitefarab.org',
'source_post_url': 'www.mitefarab.org',
'source_tld': '',
'tags': None,
'trending_datetime': '0000-00-00 00:00:00',
'type': 'gif',
'update_datetime': None,
'url': 'https://giphy.com/gifs/MITEF-mitefarab-asc2020-J0JGg6doLfmV0yZmIB',
'user': {'avatar_url': 'https://media2.giphy.com/avatars/MITEF/8FTlysEjtXzx.jpg',
'banner_url': '',
'display_name': 'MITEF Pan Arab',
'profile_url': 'https://giphy.com/MITEF/',
'twitter': None,
'username': 'MITEF'},
'username': 'MITEF'},
{'bitly_gif_url': 'https://gph.is/g/ZdxQQpP',
'bitly_url': 'https://gph.is/g/ZdxQQpP',
'content_url': '',
'create_datetime': None,
'embed_url': 'https://giphy.com/embed/hTJF0O4vDkJsUi1h8Q',
'featured_tags': None,
'id': 'hTJF0O4vDkJsUi1h8Q',
'images': {'downsized': {'height': '480',
'size': '310971',
'url': 'https://media3.giphy.com/media/hTJF0O4vDkJsUi1h8Q/giphy.gif?cid=ecefd82565bc1664c2b17e3e4b60d88c736d0c6b5a39d682&rid=giphy.gif',
'width': '480'},
'preview': {'height': '480',
'mp4': 'https://media3.giphy.com/media/hTJF0O4vDkJsUi1h8Q/giphy-preview.mp4?cid=ecefd82565bc1664c2b17e3e4b60d88c736d0c6b5a39d682&rid=giphy-preview.mp4',
'mp4_size': '15536',
'width': '480'},
'preview_gif': {'height': '480',
'size': '22387',
'url': 'https://media3.giphy.com/media/hTJF0O4vDkJsUi1h8Q/giphy-preview.gif?cid=ecefd82565bc1664c2b17e3e4b60d88c736d0c6b5a39d682&rid=giphy-preview.gif',
'width': '480'}},
'import_datetime': '2019-07-19 22:27:40',
'is_anonymous': None,
'is_community': None,
'is_featured': None,
'is_hidden': None,
'is_indexable': None,
'is_realtime': None,
'is_removed': None,
'is_sticker': False,
'rating': 'g',
'slug': 'RecargaPay-cashback-recargapay-paguetudopelocelular-hTJF0O4vDkJsUi1h8Q',
'source': 'www.recargapay.com.br',
'source_post_url': 'www.recargapay.com.br',
'source_tld': '',
'tags': None,
'trending_datetime': '0000-00-00 00:00:00',
'type': 'gif',
'update_datetime': None,
'url': 'https://giphy.com/gifs/RecargaPay-cashback-recargapay-paguetudopelocelular-hTJF0O4vDkJsUi1h8Q',
'user': {'avatar_url': 'https://media0.giphy.com/avatars/RecargaPay/msKTiPaVkvqd.png',
'banner_url': 'https://media0.giphy.com/headers/RecargaPay/kg023vdaAaWA.gif',
'display_name': 'RecargaPay',
'profile_url': 'https://giphy.com/RecargaPay/',
'twitter': None,
'username': 'RecargaPay'},
'username': 'RecargaPay'}],
'meta': {'msg': 'OK',
'response_id': '65bc1664c2b17e3e4b60d88c736d0c6b5a39d682',
'status': 200},
'pagination': {'count': 2, 'offset': 0, 'total_count': 10}}
I go though your code everything is correct except return JsonResponse(api_response.data[0]) in your views
JsonResponse:
The first parameter, data, should be a dict instance. If the safe parameter is set to False, it can be any JSON-serializable object. official documentation link
When you say
1. safe=True
return JsonResponse(api_response.data[0])
TypeError: In order to allow non-dict objects to be serialized set the safe parameter to False.
The error is obvious api_response.data[0] is not dict, see point 2 error
2
safe=False
return JsonResponse(api_response.data[0], safe=False)
TypeError: Object of type Gif is not JSON serializable
The data api_response.data[0] you provide to JsonResponse is not a dict type object actually, that's why you got error for first point.
when you say safe=False JsonResponse is trying to serialize object but that object is not json serializable, you can trace-back error
File "....\Python\Python38\lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Gif is not JSON serializable
Can be followed the link to see which object can be Json serializable
Coming back to your error.
I don't get this since api_response.data[0] is a cristal clear dictionary.
type of api_response and api_response.data[0]
type(api_response)
<class 'giphy_client.models.inline_response_200.InlineResponse200'>
type(api_response.data[0])
<class 'giphy_client.models.gif.Gif'>
You can follow for giphy_client documentation link for more-details
Solution:
result = api_response.data[0].to_dict() ## NOTE to_dict function of giphy_client.models.gif.Gif
return JsonResponse(result)
render(request, template_name, context=None, content_type=None, status=None, using=None)
render() Combines a given template with a given context dictionary
and returns an HttpResponse object with that rendered text.
You can either use Django defaults JsonResponse class or Django REST framework Response class to return JSON responses.
from django.http import JsonResponse
return JsonResponse(data=api_response.data)
from rest_framework.response import Response
return Response(data=api_response.data)
tried it on the ipython shell and it works just fine.
In [15]: response = Response(api_response.data[0])
In [16]: response
Out[16]: <Response status_code=200, "text/html; charset=utf-8">
response.data gives me the serialized response.
Python has a built in function for converting dicts to json.
import json
data = api_response.data
return render(request, json.dumps(data))
If you use that in your return statement it should return json.

Google AdWords API v201802: fields selector not working with python libraries

I am connecting to Google AdWords via API v201802 and most recent Python3 googleads module. The connection works fine and I can retrieve data for Campaigns or Ad Groups but the fields selector seems not to work. I'd like to request only a few fields, but I receive all available fields. Am I overlooking something?
from googleads import adwords
adwords_client = adwords.AdWordsClient.LoadFromStorage()
ad_group_service = adwords_client.GetService('AdGroupService', version='v201802')
selector = {
'fields': ['Id', 'Name', 'Status', 'CampaignId'],
'paging': {
'startIndex': '0',
'numberResults': '500'
}
}
page = ad_group_service.get(selector)
print(page)
Result:
{
'totalNumEntries': 138,
'Page.Type': 'AdGroupPage',
'entries': [
{
'id': 44831117552,
'campaignId': 888843682,
'campaignName': None,
'name': '001_0001_BMM_xxx',
'status': 'ENABLED',
'settings': [],
'labels': [],
'forwardCompatibilityMap': [],
'biddingStrategyConfiguration': None,
'contentBidCriterionTypeGroup': None,
'baseCampaignId': None,
'baseAdGroupId': None,
'trackingUrlTemplate': None,
'finalUrlSuffix': None,
'urlCustomParameters': None,
'adGroupType': None,
'adGroupAdRotationMode': None
},
...
] }
Of course I can filter out the unneeded fields when processing the response, but I wonder why the fields selector is not working...
I just found an answer to this in adwords-api google groups:
Hi Kevin,
The API will always include the fields your are requesting in the
response, but it might also add other fields that will be grouped
together to some of your original fields.
Best,
David Torres - AdWords API Team

Django REST ImageField Serializer close file

I want to do bulk images POST to the server.
And the same image will be upload to multiple records in Django 1.11 and Django REST 3.6.1
for image in images:
data = {
'type': image_type,
'attribute': {
'dealer_id': int(dealer_id),
},
'defaults': {
'created_user': user,
'updated_user': user,
'image': image,
}
}
for shop_id in shops:
DisplayImage.objects.update_or_create(**data)
First image does not raises the error. During debugging I had try query that DisplayImage instance, but it returns empty queryset. It is not a problem because ORM may be lazy-commit.
The error I have is I/O Operation on closed file
Update:
To keep attention from the community. I will keep adding information while I am working on this until I give up.
data == copy_data
Out[2]: False
data
Out[3]:
{'attribute': {'dealer_id': 2},
'created_user': <SimpleLazyObject: <User: admin>>,
'image': <InMemoryUploadedFile: コーティング_車内清掃_室内清掃+除菌抗菌消臭_内容.png (image/png)>,
'type': 1,
'updated_user': <SimpleLazyObject: <User: admin>>}
copy_data
Out[4]:
{'attribute': {'dealer_id': 2},
'created_user': <User: admin>,
'image': <InMemoryUploadedFile: コーティング_車内清掃_室内清掃+除菌抗菌消臭_内容.png (image/png)>,
'type': 1,
'updated_user': <User: admin>}
I had tried copy.deepcopy(data) which is a dict that I want to create an instance of DisplayImage, but when the first one went to the database the next one got closed!
I am ware that it must be different object that is the reason why I check the value by data == copy_data and it returns False

String indices must be integers - Django

I have a pretty big dictionary which looks like this:
{
'startIndex': 1,
'username': 'myemail#gmail.com',
'items': [{
'id': '67022006',
'name': 'Adopt-a-Hydrant',
'kind': 'analytics#accountSummary',
'webProperties': [{
'id': 'UA-67522226-1',
'name': 'Adopt-a-Hydrant',
'websiteUrl': 'https://www.udemy.com/,
'internalWebPropertyId': '104343473',
'profiles': [{
'id': '108333146',
'name': 'Adopt a Hydrant (Udemy)',
'type': 'WEB',
'kind': 'analytics#profileSummary'
}, {
'id': '132099908',
'name': 'Unfiltered view',
'type': 'WEB',
'kind': 'analytics#profileSummary'
}],
'level': 'STANDARD',
'kind': 'analytics#webPropertySummary'
}]
}, {
'id': '44222959',
'name': 'A223n',
'kind': 'analytics#accountSummary',
And so on....
When I copy this dictionary on my Jupyter notebook and I run the exact same function I run on my django code it runs as expected, everything is literarily the same, in my django code I'm even printing the dictionary out then I copy it to the notebook and run it and I get what I'm expecting.
Just for more info this is the function:
google_profile = gp.google_profile # Get google_profile from DB
print(google_profile)
all_properties = []
for properties in google_profile['items']:
all_properties.append(properties)
site_selection=[]
for single_property in all_properties:
single_propery_name=single_property['name']
for single_view in single_property['webProperties'][0]['profiles']:
single_view_id = single_view['id']
single_view_name = (single_view['name'])
selections = single_propery_name + ' (View: '+single_view_name+' ID: '+single_view_id+')'
site_selection.append(selections)
print (site_selection)
So my guess is that my notebook has some sort of json parser installed or something like that? Is that possible? Why in django I can't access dictionaries the same way I can on my ipython notebooks?
EDITS
More info:
The error is at the line: for properties in google_profile['items']:
Django debug is: TypeError at /gconnect/ string indices must be integers
Local Vars are:
all_properties =[]
current_user = 'myemail#gmail.com'
google_profile = `the above dictionary`
So just to make it clear for who finds this question:
If you save a dictionary in a database django will save it as a string, so you won't be able to access it after.
To solve this you can re-convert it to a dictionary:
The answer from this post worked perfectly for me, in other words:
import json
s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"
json_acceptable_string = s.replace("'", "\"")
d = json.loads(json_acceptable_string)
# d = {u'muffin': u'lolz', u'foo': u'kitty'}
There are many ways to convert a string to a dictionary, this is only one. If you stumbled in this problem you can quickly check if it's a string instead of a dictionary with:
print(type(var))
In my case I had:
<class 'str'>
before converting it with the above method and then I got
<class 'dict'>
and everything worked as supposed to

Categories

Resources