简体   繁体   English

如何使用自定义存储属性在django中模拟媒体文件目录?

[英]How to mock media file directory in django with custom storage property?

django version: 1.11, python version: 3.6.3 Django版本:1.11,python版本:3.6.3

According to this two blogs/articles: 根据这两个博客/文章:

https://joeray.me/mocking-files-and-file-storage-for-testing-django-models.html https://www.caktusgroup.com/blog/2013/06/26/media-root-and-django-tests/ https://joeray.me/mocking-files-and-file-storage-for-testing-django-models.html https://www.caktusgroup.com/blog/2013/06/26/media-root-and -django-tests /

we would, ideally, use a temporary directory to upload the mock-files. 理想情况下,我们将使用临时目录上载模拟文件。 Now, mocking the files is easy. 现在,模拟文件很容易。 But mocking the directory and using a temporary directory is not working with custom storage property 但是模拟目录并使用临时目录不适用于自定义存储属性

in settings.py i have a protected root to upload non public images: settings.py我具有受保护的根目录来上传非公共图像:

MEDIA_URL = '/media/'

MEDIA_ROOT=os.path.join(BASE_DIR, "cdn", "media")
PROTECTED_ROOT = os.path.join(BASE_DIR, "cdn", "protected")

in products/models.py i have: products/models.py我有:

from django.conf import settings
from django.db import models
from django.core.files.storage import FileSystemStorage

class Product(models.Model):
    media = models.ImageField(
            # custom storage property
            storage=FileSystemStorage(location=settings.PROTECTED_ROOT)
        )

and the test in products/tests/test_views.py : 并在products/tests/test_views.py

from django.test import TestCase
from unittest import mock
from products.models import Product
from django.core.files import File

class ProductViewSetup(TestCase):                                                                                                                                        

    @classmethod                                                                                                                                                         
    def setUpTestData(cls):
        file_mock = mock.MagicMock(spec=File, name='FileMock')                                                                                                           
        file_mock.name = 'test.jpg'
        cls.product = Product.objects.create(
                media=file_mock
            )

i thought i could just customize the code described in caktusgroup blog to: 我以为我可以将caktusgroup博客中描述的代码自定义为:

class TempMediaMixin(object):                                                                                                                                            
    "Mixin to create MEDIA_ROOT in temp and tear down when complete."                                                                                                    

    def setup_test_environment(self):                                                                                                                                    
        "Create temp directory and update MEDIA_ROOT and default storage."                                                                                               
        super(TempMediaMixin, self).setup_test_environment()                                                                                                             
        settings._original_media_root = settings.MEDIA_ROOT                                                                                                              
        settings._original_file_storage = settings.DEFAULT_FILE_STORAGE                                                                                                  
        settings._original_protected_root = settings.PROTECTED_ROOT                                                                                                      
        self._temp_media = tempfile.mkdtemp()                                                                                                                            
        self._temp_protected = tempfile.mkdtemp()                                                                                                                        
        settings.MEDIA_ROOT = self._temp_media                                                                                                                           
        settings.PROTECTED_ROOT = self._temp_protected                                                                                                                   
        settings.DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'                                                                                    

    def teardown_test_environment(self):                                                                                                                                 
        "Delete temp storage."                                                                                                                                           
        super(TempMediaMixin, self).teardown_test_environment()                                                                                                          
        shutil.rmtree(self._temp_media, ignore_errors=True)                                                                                                              
        shutil.rmtree(self._temp_protected, ignore_errors=True)                                                                                                          
        settings.MEDIA_ROOT = settings._original_media_root                                                                                                              
        del settings._original_media_root                                                                                                                                
        settings.PROTECTED_ROOT = settings._original_protected_root                                                                                                      
        del settings._original_protected_root                                                                                                                            
        settings.DEFAULT_FILE_STORAGE = settings._original_file_storage                                                                                                  
        del settings._original_file_storage                                                                                                                              


class CustomTestSuiteRunner(TempMediaMixin, DiscoverRunner):                                                                                                             
    "Local test suite runner."  

i added TEST_RUNNER to settings.py , and the CustomTestSuiteRunner is working. 我将TEST_RUNNER添加到settings.py ,并且CustomTestSuiteRunner正在工作。 The temporary directory is also used, but still files are added to my PROTECTED_ROOT , how do i fix this? 还使用了临时目录,但仍将文件添加到我的PROTECTED_ROOT ,如何解决此问题?

It seems like the custom test runner works fine when I overwrite the storage location in setUpTestData() : 当我覆盖setUpTestData()的存储位置时,自定义测试运行器似乎运行良好:

Product.media.field.storage.location = settings.PROTECTED_ROOT

This way it will use the temporary directory when using the custom test runner. 这样,在使用自定义测试运行器时它将使用临时目录。

If you don't overwrite the storage location, it will use the storage defined in models.py . 如果不覆盖存储位置,它将使用models.py定义的存储。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM