From 7fc56b77db16e7e0783a4ba52b8ed5ef09ce9558 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Tue, 29 Sep 2015 16:46:45 +0200 Subject: [PATCH] Fixed #98 -- Handle deletion of cached files --- src/pretix/base/models.py | 15 ++++++++++++--- src/tests/base/test_models.py | 26 ++++++++++++++++++++------ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/pretix/base/models.py b/src/pretix/base/models.py index b0169acb31..5093742d35 100644 --- a/src/pretix/base/models.py +++ b/src/pretix/base/models.py @@ -13,6 +13,8 @@ from django.contrib.auth.models import ( from django.core.validators import RegexValidator from django.db import models from django.db.models import Q, Count +from django.db.models.signals import post_delete +from django.dispatch import receiver from django.template.defaultfilters import date as _date from django.utils.functional import cached_property from django.utils.timezone import now @@ -964,7 +966,7 @@ class Item(Versionable): # that changes the price, the default price has no effect. newprice = None - for receiver, response in responses: + for rec, response in responses: if 'available' in response[i] and not response[i]['available']: var['available'] = False break @@ -1018,7 +1020,7 @@ class Item(Versionable): cache=self.event.get_cache() ) price = self.default_price - for receiver, response in responses: + for rec, response in responses: if 'available' in response[0] and not response[0]['available']: return False elif 'price' in response[0] and response[0]['price'] is not None and response[0]['price'] < price: @@ -1126,7 +1128,7 @@ class ItemVariation(Versionable): cache=self.item.event.get_cache() ) price = self.default_price if self.default_price is not None else self.item.default_price - for receiver, response in responses: + for rec, response in responses: if 'available' in response[0] and not response[0]['available']: return False elif 'price' in response[0] and response[0]['price'] is not None and response[0]['price'] < price: @@ -1821,3 +1823,10 @@ class EventLock(models.Model): class LockReleaseException(Exception): pass + + +@receiver(post_delete, sender=CachedFile) +def cached_file_delete(sender, instance, **kwargs): + if instance.file: + # Pass false so FileField doesn't save the model. + instance.file.delete(False) diff --git a/src/tests/base/test_models.py b/src/tests/base/test_models.py index 790e61f09a..e9fffafc84 100644 --- a/src/tests/base/test_models.py +++ b/src/tests/base/test_models.py @@ -1,10 +1,12 @@ from datetime import timedelta +from django.core.files.storage import default_storage +from django.core.files.uploadedfile import SimpleUploadedFile from django.test import TestCase from django.utils.timezone import now from pretix.base.models import ( - CartPosition, Event, Item, ItemCategory, ItemVariation, Order, + CachedFile, CartPosition, Event, Item, ItemCategory, ItemVariation, Order, OrderPosition, Organizer, Property, PropertyValue, Question, Quota, User, ) from pretix.base.services.orders import mark_order_paid @@ -16,6 +18,7 @@ class ItemVariationsTest(TestCase): This test case tests various methods around the properties / variations concept. """ + @classmethod def setUpTestData(cls): o = Organizer.objects.create(name='Dummy', slug='dummy') @@ -141,7 +144,6 @@ class ItemVariationsTest(TestCase): class VersionableTestCase(TestCase): - def test_shallow_cone(self): o = Organizer.objects.create(name='Dummy', slug='dummy') event = Event.objects.create( @@ -159,7 +161,6 @@ class VersionableTestCase(TestCase): class UserTestCase(TestCase): - def test_name(self): u = User.objects.create_user('test@foo.bar', 'test') u.givenname = "Christopher" @@ -184,7 +185,6 @@ class UserTestCase(TestCase): class BaseQuotaTestCase(TestCase): - @classmethod def setUpTestData(cls): o = Organizer.objects.create(name='Dummy', slug='dummy') @@ -208,7 +208,6 @@ class BaseQuotaTestCase(TestCase): class QuotaTestCase(BaseQuotaTestCase): - def test_available(self): self.quota.items.add(self.item1) self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 2)) @@ -304,7 +303,6 @@ class QuotaTestCase(BaseQuotaTestCase): class OrderTestCase(BaseQuotaTestCase): - def setUp(self): super().setUp() self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy') @@ -388,6 +386,7 @@ class ItemCategoryTest(TestCase): """ This test case tests various methods around the category model. """ + @classmethod def setUpTestData(cls): o = Organizer.objects.create(name='Dummy', slug='dummy') @@ -409,3 +408,18 @@ class ItemCategoryTest(TestCase): c2.position = 2 assert c1 < c2 assert c2 > c1 + + +class CachedFileTestCase(TestCase): + def test_file_handling(self): + cf = CachedFile() + val = SimpleUploadedFile("testfile.txt", b"file_content") + cf.file.save("testfile.txt", val) + cf.type = "text/plain" + cf.filename = "testfile.txt" + cf.save() + assert default_storage.exists(cf.file.name) + with default_storage.open(cf.file.name, 'r') as f: + assert f.read().strip() == "file_content" + cf.delete() + assert not default_storage.exists(cf.file.name)