我正在开发一个AWS S3
用于服务static
/media
文件的 Django 项目。为此,我以这篇文章为例,安装了 boto3 和 django-storages。
我们的项目还用于FactoryBoy
帮助我们进行测试。但是,新设置会导致所有工厂出现FileFields
或ImageFields
失败并出现以下错误:TypeError: expected string or bytes-like object
模型如下:
class AcademySettings(models.Model):
(...)
logo = models.ImageField(
blank=True,
null=True,
storage=PublicMediaStorage(),
)
它使用PublicMediaStorage()
对象,灵感来自上面链接的帖子,其定义如下:
class PublicMediaStorage(S3Boto3Storage):
""" Public media """
location = settings.AWS_PUBLIC_MEDIA_LOCATION
file_overwrite = False
该型号有以下工厂:
class AcademySettingsFactory(factory.DjangoModelFactory):
class Meta:
model = 'core.AcademySettings'
(...)
logo = factory.django.ImageField(color='red')
该类PublicMediaStorage
使用AWS_PUBLIC_MEDIA_LOCATION
在设置中定义的变量:
AWS_STORAGE_BUCKET_NAME: str = 'project-name-hidden'
AWS_STORAGE_BUCKET_NAME: str = 'project-name-hidden'
AWS_S3_CUSTOM_DOMAIN: str = '{}.s3.amazonaws.com'.format(
AWS_STORAGE_BUCKET_NAME
)
AWS_LOCATION: str = 'backend'
AWS_PUBLIC_MEDIA_LOCATION: str = AWS_LOCATION + '/public'
最后,这个测试本身——为了这篇文章的目的,一个简单的 init 就足够了:
class TestAcademySettingsModel(TestCase):
def setUp(self) -> None:
self.academy_settings = AcademySettingsFactory()
def test_init(self) -> None:
self.assertTrue(self.academy_settings)
似乎由生成的值factory.django.ImageField()
与正确的设置不兼容django-storages
,但我不确定如何解决这个问题。
我们的项目具有非常高的测试覆盖率,并且FactoryBoy
几乎在所有项目中都有使用,因此放弃FactoryBoy
并不是一个真正的选择。
我想知道是否有其他人使用两者创建了一个项目FactoryBoy
,django-storages
以及他们是否也遇到了这些问题(如果是,你是如何解决这些问题的?)
---------------------------------------------------------------------------
编辑
根据要求,我已按要求包含了堆栈跟踪
Traceback (most recent call last):
File "/home/jasper/PycharmProjects/ewise_backend/src/core/tests/testmodels.py", line 102, in setUp
self.academy_settings = c_factories.AcademySettingsFactory()
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/factory/base.py", line 46, in __call__
return cls.create(**kwargs)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/factory/base.py", line 564, in create
return cls._generate(enums.CREATE_STRATEGY, kwargs)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/factory/django.py", line 141, in _generate
return super(DjangoModelFactory, cls)._generate(strategy, params)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/factory/base.py", line 501, in _generate
return step.build()
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/factory/builder.py", line 279, in build
kwargs=kwargs,
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/factory/base.py", line 315, in instantiate
return self.factory._create(model, *args, **kwargs)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/factory/django.py", line 185, in _create
return manager.create(*args, **kwargs)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/query.py", line 422, in create
obj.save(force_insert=True, using=self.db)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/base.py", line 741, in save
force_update=force_update, update_fields=update_fields)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/base.py", line 779, in save_base
force_update, using, update_fields,
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/base.py", line 870, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/base.py", line 908, in _do_insert
using=using, raw=raw)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/query.py", line 1186, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1334, in execute_sql
for sql, params in self.as_sql():
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1278, in as_sql
for obj in self.query.objs
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1278, in <listcomp>
for obj in self.query.objs
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1277, in <listcomp>
[self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1228, in pre_save_val
return field.pre_save(obj, add=True)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/fields/files.py", line 288, in pre_save
file.save(file.name, file.file, save=False)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/db/models/fields/files.py", line 87, in save
self.name = self.storage.save(name, content, max_length=self.field.max_length)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/core/files/storage.py", line 51, in save
name = self.get_available_name(name, max_length=max_length)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/storages/backends/s3boto3.py", line 620, in get_available_name
return super(S3Boto3Storage, self).get_available_name(name, max_length)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/django/core/files/storage.py", line 75, in get_available_name
while self.exists(name) or (max_length and len(name) > max_length):
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/storages/backends/s3boto3.py", line 520, in exists
self.connection.meta.client.head_object(Bucket=self.bucket_name, Key=name)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/botocore/client.py", line 276, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/botocore/client.py", line 559, in _make_api_call
api_params, operation_model, context=request_context)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/botocore/client.py", line 605, in _convert_to_request_dict
api_params, operation_model, context)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/botocore/client.py", line 637, in _emit_api_params
params=api_params, model=operation_model, context=context)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/botocore/hooks.py", line 356, in emit
return self._emitter.emit(aliased_event_name, **kwargs)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/botocore/hooks.py", line 228, in emit
return self._emit(event_name, kwargs)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/botocore/hooks.py", line 211, in _emit
response = handler(**kwargs)
File "/home/jasper/PycharmProjects/ewise_backend/venv/lib/python3.7/site-packages/botocore/handlers.py", line 223, in validate_bucket_name
if not VALID_BUCKET.search(bucket) and not VALID_S3_ARN.search(bucket):
TypeError: expected string or bytes-like object