Django 1.3 改变了带有FileField
s 的模型的行为,这样当实例被删除时,实际的文件仍然存在。对于大多数目的,这很好。但是,我正在测试一个大量使用ImageField
s 的应用程序,最终在我的开发上传目录中发现了数百个无用的剩余图像。由于它是开发,这不是什么大不了的事,但我更愿意在测试中自己清理。
测试时使这些图像不徘徊的最佳方法是什么。我强调这部分是因为我不想全面修改这种行为,使用delete
覆盖等。
Django 1.3 改变了带有FileField
s 的模型的行为,这样当实例被删除时,实际的文件仍然存在。对于大多数目的,这很好。但是,我正在测试一个大量使用ImageField
s 的应用程序,最终在我的开发上传目录中发现了数百个无用的剩余图像。由于它是开发,这不是什么大不了的事,但我更愿意在测试中自己清理。
测试时使这些图像不徘徊的最佳方法是什么。我强调这部分是因为我不想全面修改这种行为,使用delete
覆盖等。
我崩溃了,妥协了一点。我决定继续使用覆盖delete
,但我删除了依赖于传递include_images=True
kwarg 的实际图像文件。
class Photo(models.Model):
...
def delete(self, *args, **kwargs):
if kwargs.pop('include_images', False):
for field in self._meta.fields:
if type(field) == models.ImageField:
image = self.__getattribute__(field.name)
if image.name != '':
image.storage.delete(image.name)
super(Photo, self).delete(*args, **kwargs)
然后,我tearDown
在测试用例中修改了方法,如下所示:
def tearDown(self):
for p in Photo.objects.all():
p.delete(include_images=True)
我对这个解决方案并不完全满意,但它是我能得到的最接近我认为理想的解决方案。这真的应该由测试本身来处理。
我遇到了这个问题,并在 Google 中找到了这篇文章。我更喜欢使用命令 - 所以这里有一些可能对其他人有用的代码。这是在 Django 1.4 中,但应该适用于任何版本。我使用WebTest:
在基础测试类中:
def get_test_image_input(self):
return (
'_test-image.jpg',
file(os.path.join(settings.TEST_FILES_PATH, "images", "test.jpg")).read()
)
在任何测试中:
form['image'] = self.get_test_image_input()
之后要清理,我只需在命令中删除以_test-image开头的所有文件:
from django.core.management.base import BaseCommand
from fabric.operations import local
class Command(BaseCommand):
def handle(self, *args, **options):
# test an app call "tests"
local("python manage_test.py test tests -v 2")
# could use call_command(...) instead
# remove all test images
local("sudo rm -rf `find . -name _test-image*`")