1

我正在开发一个AWS S3用于服务static/media文件的 Django 项目。为此,我以这篇文章为例,安装了 boto3 和 django-storages。

我们的项目还用于FactoryBoy帮助我们进行测试。但是,新设置会导致所有工厂出现FileFieldsImageFields失败并出现以下错误: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并不是一个真正的选择。

我想知道是否有其他人使用两者创建了一个项目FactoryBoydjango-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
4

0 回答 0