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
Related
I'm currently trying to carry over object relationship functionality from a php backend to a python backend. In the php application you were able to have a call like so:
~api/v1/cats/5b40b6eb-538f-a015-9196-1cc63cf8d7ae
That would return a result like this:
{
id: "5b40b6eb-538f-a015-9196-1cc63cf8d7ae",
name: "mittens",
hatId: "0845de76-9d68-cfee-0ebb-473ccddf16bc",
}
The functionality that I am trying to replicate is that if you added an include param to the call with the name of foreign object like this:
~api/v1/cats/5b40b6eb-538f-a015-9196-1cc63cf8d7ae?include=hat
Then it would return the original object including the foreign key object
{
id: "5b40b6eb-538f-a015-9196-1cc63cf8d7ae",
name: "mittens",
hatId: "0845de76-9d68-cfee-0ebb-473ccddf16bc",
hat: {
id: "0845de76-9d68-cfee-0ebb-473ccddf16bc",
name: 'top hat',
}
}
All that I've come across so far is select_related, HyperlinkedRelatedField, and prefetch_related; none of these seem to be able to get the above result when implemented.
I would strongly recommend using Django Rest Framework, and specifically look at nested relationships.
The example given in the DRF docs matches what you're looking to do almost exactly (though note, it's a one-to-many field, while your example is a one-to-one field):
>>> album = Album.objects.create(album_name="The Grey Album", artist='Danger Mouse')
>>> Track.objects.create(album=album, order=1, title='Public Service Announcement', duration=245)
<Track: Track object>
>>> Track.objects.create(album=album, order=2, title='What More Can I Say', duration=264)
<Track: Track object>
>>> Track.objects.create(album=album, order=3, title='Encore', duration=159)
<Track: Track object>
>>> serializer = AlbumSerializer(instance=album)
>>> serializer.data
{
'album_name': 'The Grey Album',
'artist': 'Danger Mouse',
'tracks': [
{'order': 1, 'title': 'Public Service Announcement', 'duration': 245},
{'order': 2, 'title': 'What More Can I Say', 'duration': 264},
{'order': 3, 'title': 'Encore', 'duration': 159},
...
],
}
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
I am using Django 1.9.5 and have a problem with the data that python social auth gives. I got the data, but I cant' access it. This is my code
def save_auth_data_session(request):
if request.user:
twitter = request.user.social_auth.get(provider ='twitter')
print twitter.extra_data['access_token']
The terminal gives me this error
""TypeError: string indices must be integers""
If I do a "print vars(twitter)", this the data I get
{'user_id': 123, 'uid': u'2413671427750', '_user_cache': <User: quintana>, '_state': <django.db.models.base.ModelState object at 0x7fa3d86fc2d0>, 'provider': u'twitter', 'extra_data': u'{"access_token": {"oauth_token_secret": "Afkasdasdas21zxbxcbn", "oauth_token": "2468cxcpqsldkenI56", "x_auth_expires": "0", "user_id": "455793463", "screen_name": "puertoRico"}, "id": 455793463}', 'id': 123}
As i can see from output of print vars(twitter) - extra_data stores serialized dictionary (string) 'extra_data': u'{...}'.
So you need to deserialize it first.
import json
twitter = request.user.social_auth.get(provider ='twitter')
extra_data = json.loads(twitter.extra_data) # will give you a python dictionary
print extra_data['access_token']
I want to save an array of objects passed from javascript through ajax to me database. This is my view code:
data2 = json.loads(request.raw_get_data)
for i in data2:
print(key)
obj = ShoppingCart(quantity = i.quantity , user_id = 3, datetime = datetime.now(), product_id = i.pk)
obj.save()
return render_to_response("HTML.html",RequestContext(request))
After the first line, i get this in my dictionary:
[{'model': 'Phase_2.product', 'fields': {'name': 'Bata', 'category': 2, 'quantity': 1, 'subcategory': 1, 'count': 2, 'price': 50}, 'imageSource': None, 'pk': 1}]
(Only one object in the array right now)
I want to be able access individual fields like quantity, id, etc in order to save the data to my database. When i debug this code, it gives a name error on 'i'. I also tried accessing the fields like this: data2[0].quantity but it gives this error: {AttributeError}dict object has no attribute quantity.
Edited code:
for i in data2:
name = i["fields"]["name"]
obj = ShoppingCart(quantity = i["fields"]["quantity"] , user_id = 3, datetime = datetime.now(), product_id = i["fields"]["pk"])
obj.save()
It might help you to visualise the returned dict with proper formatting:
[
{
'model': 'Phase_2.product',
'fields': {
'name': 'Bata',
'category': 2,
'quantity': 1,
'subcategory': 1,
'count': 2,
'price': 50
},
'imageSource': None,
'pk': 1
}
]
The most likely reason for your error is that you are trying to access values of of the inner 'fields' dictionary as if they belong to the outer i dictionary.
i.e.
# Incorrect
i["quantity"]
# Gives KeyError
# Correct
i["fields"]["quantity"]
Edit
You have the same problem in your update:
# Incorrect
i["fields"]["pk"]
# Correct
i["pk"]
The "pk" field is in the outer dictionary, not the inner "fields" dictionary.
You may try:
i['fields']['quantity']
The json.loads() returns you a dictionary, which should be accessed by key.
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()