diff --git a/pinry/core/api.py b/pinry/core/api.py index c516538..56a4b21 100644 --- a/pinry/core/api.py +++ b/pinry/core/api.py @@ -59,7 +59,7 @@ class UserResource(ModelResource): def filter_generator_for(size): def wrapped_func(bundle, **kwargs): - return Thumbnail.objects.get_or_create_at_size(bundle.obj.pk, size, **kwargs) + return bundle.obj.get_by_size(size) return wrapped_func diff --git a/pinry/core/models.py b/pinry/core/models.py index 9b6f85f..68d39cc 100644 --- a/pinry/core/models.py +++ b/pinry/core/models.py @@ -1,10 +1,11 @@ import requests from cStringIO import StringIO +from django.conf import settings from django.core.files.uploadedfile import InMemoryUploadedFile -from django.db import models +from django.db import models, transaction -from django_images.models import Image as BaseImage +from django_images.models import Image as BaseImage, Thumbnail from taggit.managers import TaggableManager from ..users.models import User @@ -19,7 +20,13 @@ class ImageManager(models.Manager): buf.write(response.content) obj = InMemoryUploadedFile(buf, 'image', file_name, None, buf.tell(), None) - return Image.objects.create(image=obj) + # create the image and its thumbnails in one transaction, removing + # a chance of getting Database into a inconsistent state when we + # try to create thumbnails one by one later + image = self.create(image=obj) + for size in settings.IMAGE_SIZES.keys(): + Thumbnail.objects.get_or_create_at_size(image.pk, size) + return image class Image(BaseImage): diff --git a/pinry/core/tests/helpers.py b/pinry/core/tests/helpers.py index ce4e6fd..67435ef 100644 --- a/pinry/core/tests/helpers.py +++ b/pinry/core/tests/helpers.py @@ -3,6 +3,7 @@ from django.contrib.auth.models import Permission from django.core.files.images import ImageFile from django.db.models.query import QuerySet from django.test import TestCase +from django_images.models import Thumbnail import factory from taggit.models import Tag @@ -33,8 +34,15 @@ class TagFactory(factory.Factory): class ImageFactory(factory.Factory): + FACTORY_FOR = Image + image = factory.LazyAttribute(lambda a: ImageFile(open(TEST_IMAGE_PATH, 'rb'))) + @factory.post_generation() + def create_thumbnails(self, create, extracted, **kwargs): + for size in settings.IMAGE_SIZES.keys(): + Thumbnail.objects.get_or_create_at_size(self.pk, size) + class PinFactory(factory.Factory): submitter = factory.SubFactory(UserFactory) diff --git a/pinry/core/views.py b/pinry/core/views.py index 5b57c4b..8192705 100644 --- a/pinry/core/views.py +++ b/pinry/core/views.py @@ -1,9 +1,11 @@ from django.http import HttpResponseRedirect +from django.conf import settings from django.core.urlresolvers import reverse from django.views.generic import CreateView from django_images.models import Image from braces.views import JSONResponseMixin, LoginRequiredMixin +from django_images.models import Thumbnail from .forms import ImageForm @@ -20,6 +22,8 @@ class CreateImage(JSONResponseMixin, LoginRequiredMixin, CreateView): def form_valid(self, form): image = form.save() + for size in settings.IMAGE_SIZES.keys(): + Thumbnail.objects.get_or_create_at_size(image.pk, size) return self.render_json_response({ 'success': { 'id': image.id