2009-10-24 17 views
5

Próbuję przesłać i zapisać obraz o zmienionym rozmiarze w polu db.BlobProperty w Google App Engine przy użyciu Django.Przechowywanie obrazów w App Engine przy użyciu Django

odpowiednia część mojego zdania, że ​​przetworzyć żądania wygląda następująco:

image = images.resize(request.POST.get('image'), 100, 100) 
recipe.large_image = db.Blob(image) 
recipe.put() 

Który Wygląda byłoby logicznym Django odpowiednik przykład w docs:

from google.appengine.api import images 

class Guestbook(webapp.RequestHandler): 
    def post(self): 
    greeting = Greeting() 
    if users.get_current_user(): 
     greeting.author = users.get_current_user() 
    greeting.content = self.request.get("content") 
    avatar = images.resize(self.request.get("img"), 32, 32) 
    greeting.avatar = db.Blob(avatar) 
    greeting.put() 
    self.redirect('/') 

(źródło: http://code.google.com/appengine/docs/python/images/usingimages.html#Transform)

Ale nadal pojawia się błąd z informacją: NotImageError/Empty image data.

i odnosi się do tej linii:

image = images.resize(request.POST.get('image'), 100, 100) 

Mam problemy z dostaniem się do danych obrazu. Wygląda na to, że nie jest on przesyłany, ale nie wiem, dlaczego. Moja forma ma enctype = "multipart/form-data" i wszystko to. Myślę, że coś jest nie tak z tym, jak mam na myśli dane obrazu. "request.POST.get (" image ")", ale nie wiem, jak inaczej się do niego odwoływać. Jakieś pomysły?

Z góry dziękuję.

Odpowiedz

9

Po kilku wskazówkach od "halo" wymyśliłem problem. Po pierwsze, domyślna wersja Django dostarczana w pakiecie z App Engine to wersja 0.96 i od tego czasu zmieniła się struktura obsługiwanych przez nią plików. Jednak w celu zachowania zgodności ze starszymi aplikacjami trzeba wyraźnie powiedzieć App Engine używać Django 1.1 tak:

from google.appengine.dist import use_library 
use_library('django', '1.1') 

Możesz przeczytać więcej o tym in the app engine docs.

Ok, więc oto rozwiązanie:

from google.appengine.api import images 

image = request.FILES['large_image'].read() 
recipe.large_image = db.Blob(images.resize(image, 480)) 
recipe.put() 

Następnie, aby służyć dynamicznych obrazów z powrotem z magazynu danych, zbudować obsługi dla obrazów tak:

from django.http import HttpResponse, HttpResponseRedirect 

def recipe_image(request,key_name): 
    recipe = Recipe.get_by_key_name(key_name) 

    if recipe.large_image: 
     image = recipe.large_image 
    else: 
     return HttpResponseRedirect("/static/image_not_found.png") 

    #build your response 
    response = HttpResponse(image) 
    # set the content type to png because that's what the Google images api 
    # stores modified images as by default 
    response['Content-Type'] = 'image/png' 
    # set some reasonable cache headers unless you want the image pulled on every request 
    response['Cache-Control'] = 'max-age=7200' 
    return response 
3

Masz dostęp do przesłanych danych przez request.FILES ['field_name'].

http://docs.djangoproject.com/en/dev/topics/http/file-uploads/


Reading więcej o Google API obrazu, wydaje mi się, należy robić coś takiego:.

from google.appengine.api import images 

image = Image(request.FILES['image'].read()) 
image = image.resize(100, 100) 
recipe.large_image = db.Blob(image) 
recipe.put() 

request.FILES [ 'Obraz'] read() powinien działać, ponieważ ma być instancją Django UploadedFile.

+0

dzięki za pomoc hcalves , Nadal muszę coś robić nie tak, ponieważ zmieniłem to: image = images.resize (request.FILES ['image'], 300, 200) recipe.large_image = db.Blob (image) przepis. put() Teraz otrzymuję BadImageError w wywołaniu resize(). Ponadto GAE domyślnie używa django .96 ...może powinienem spróbować to zmienić? Próbowałem również wykonać request.FILES ['image']. Read(), ale to nie zadziałało. Mówi mi, że "obiekt" dyktujący nie ma atrybutu "czytaj" " Będę z tym jutro bałaganił. Ale jeśli masz jakieś sugestie, jestem tylko uszy. Dzięki jeszcze raz. –