Estoy creando un código de población para completar el modelo 'Ciudad' de Django con imágenes de la API de Google Places.
Este es el modelo:
class City(models.Model): city_image = models.ImageField(blank=True, upload_to='city_pictures')Creé la URL de la API que devuelve una foto:
#fetch image from this url city_image_url = ('https://maps.googleapis.com/maps/api/place/photo' '?maxwidth=%s' '&photoreference=%s' '&key=%s') % (maxwidth, city_image_ref, GoogleKey)Google dice que la respuesta es una foto y la probé en Postman, así que quiero algo como esto:
with urllib.request.urlopen(city_image_url) as response: city_image = response created_city = City.objects.get_or_create(city_id=city_id)[0] created_city.city_image = city_image #plus other fieldsPero recibo este error:
Rastreo (última llamada más reciente): Archivo "C:\Users\bnbih\Djangos\excurj_proj\population_script.py", línea 68, en populate() Archivo "C:\Users\bnbih\Djangos\excurj_proj\population_script.py" , línea 64, en poblar created_city.save() Archivo "C:\Users\bnbih\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\base.py", línea 796, en save force_update=force_update, update_fields=update_fields) Archivo "C:\Users\bnbih\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\base.py", línea 824, en save_base actualizado = self._save_table(raw, cls, force_insert, force_update, using, update_fields) Archivo "C:\Users\bnbih\AppData\Local\Programs\Python\Python36-32\lib\site-packages\ django\db\models\base.py", línea 886, en _save_table for f en non_pks] Archivo "C:\Users\bnbih\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\ db\models\base.py", línea 886, en for f en non_pks] Archivo "C:\Users\bnbih\AppData\Local\Programs\Python\Python36-32\lib\site-packages\dj ango\db\models\fields\files.py", línea 290, en pre_save if file and not file._committed: AttributeError: el objeto 'HTTPResponse' no tiene atributo '_committed'
Estoy usando Python 3 y Django 1.10
Prueba esto:
from django.core.files import File from django.core.files.temp import NamedTemporaryFile city_image = NamedTemporaryFile(delete=True) city_image.write(urllib2.urlopen(url).read()) city_image.flush() created_city = City.objects.get_or_create(city_id=city_id)[0] created_city.city_image = city_imageDespués de seguir la respuesta anterior y este tutorial
Esto funcionó para mí para guardar una imagen de Google Places en un ImageField:
Primero , prepare la URL para la cual la respuesta HTTP es una imagen:
city_image_url = ('https://maps.googleapis.com/maps/api/place/photo' '?maxwidth=%s' '&photoreference=%s' '&key=%s') % (maxwidth, city_image_ref, GoogleKey)En segundo lugar , recupere esa imagen real y guárdela en una variable:
retrieved_image = requests.get(city_image_url)En tercer lugar , cree un archivo localmente y escriba el contenido de la imagen remota en él:
with open(city_names[i] + '.jpg', 'wb') as f: f.write(retrieved_image.content)Cuarto , abra el archivo con la imagen dentro y conviértalo en un archivo Django:
reopen = open(city_names[i] + '.jpg', 'rb') django_file = File(reopen)Quinto , cree un objeto modelo y guarde el archivo django dentro de ImageField de esta manera:
created_city = City.objects.get_or_create(city_id=city_id)[0] #save it to the ImageField -> args are: 1. the name of the file that is to be saved in MEDIA_ROOT path 2. The Django file itself 3. save instance created_city.city_image.save(city_names[i] + '.jpg', django_file, save=True) created_city.save()Finalmente, estas son las importaciones que necesitas:
from django.core.files import File import requests