diff --git a/.env b/.env
index 0268899..a5a8d73 100644
--- a/.env
+++ b/.env
@@ -1,3 +1,3 @@
-PYTHON_VERSION=3.8
-DJANGO_VERSION=3.1.7
+PYTHON_VERSION=3.9.9
+DJANGO_VERSION=4.0.1
SELENIUM_VERSION=4.0.0a7
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 582713d..651728d 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -30,7 +30,7 @@ jobs:
AWS_ACCESS_KEY_ID: test
AWS_SECRET_ACCESS_KEY: test
# enable persistance
- DATA_DIR: /tmp/localstack/data
+ PERSISTENCE: 1
LAMBDA_EXECUTOR: local
DOCKER_HOST: unix:///var/run/docker.sock
DEBUG: true
@@ -38,7 +38,7 @@ jobs:
# It doesn't seem like the scripts in entrypoint are being ran... or they are not copied over since
# the checkout action happens after init services on Github Actions
# - "${{ github.workspace }}/docker-entrypoint-initaws.d:/docker-entrypoint-initaws.d"
- - "${{ github.workspace }}/tmp/localstack:/tmp/localstack"
+ - "${{ github.workspace }}/volume:/var/lib/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
ports:
- 4566:4566
@@ -46,8 +46,12 @@ jobs:
options: --health-cmd="curl http://localhost:4566/health?reload" --health-interval=10s --health-timeout=5s --health-retries=3
strategy:
matrix:
- python-version: [3.6, 3.7, 3.8, 3.9]
- django-version: [2.2, 3.0]
+ python-version: [3.8, 3.9, 3.10.0, 3.11]
+ django-version: [3.2, 4.0.4]
+ include:
+ # Version 4.0 of Django drops support for python 3.6 & 3.7
+ - python-version: 3.7
+ django-version: 3.2
env:
DJANGO_VERSION: ${{ matrix.django-version }}
PYTHON_VERSION: ${{ matrix.python-version }}
@@ -59,7 +63,7 @@ jobs:
- name: Update Permissions
run: |
sudo chown -R $USER:$USER ${{ github.workspace }}
- # required because actions/checkout@2 wants to delete the /tmp/localstack folder
+ # required because actions/checkout@2 wants to delete the localstack folder
- uses: actions/checkout@v2
- name: Build Docker for Python 3.6
if: ${{ matrix.python-version == 3.6 }}
diff --git a/.gitignore b/.gitignore
index 0228584..d50f8a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,3 +37,5 @@ docs/_build/
db.sqlite3
tmp/
+
+.python-version
diff --git a/.python-version b/.python-version
index 61d93e0..91e0b50 100644
--- a/.python-version
+++ b/.python-version
@@ -1 +1 @@
-django-admin-confirm-3.8.0
+django-admin-confirm-3.9.9
diff --git a/Dockerfile b/Dockerfile
index 714a130..d205f4c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -4,6 +4,8 @@ ENV PYTHONUNBUFFERED=1
ENV USE_DOCKER=true
WORKDIR /code
COPY . /code/
+RUN echo "Use legency resolver for pip. It does not use the feature back-tracking. Thus is easier to debug imcompatible dependencies."
+RUN pip install --upgrade pip --use-deprecated=legacy-resolver
ARG DJANGO_VERSION="3.1.7"
RUN echo "Installing Django Version: ${DJANGO_VERSION}"
RUN pip install django==${DJANGO_VERSION}
diff --git a/Makefile b/Makefile
index b0d2557..54f1af9 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ test-integration:
coverage run --source admin_confirm --branch -m pytest --ignore=admin_confirm/tests/unit
docker-exec:
- docker-compose exec -T web ${COMMAND}
+ docker-compose -f docker-compose.dev.yml exec -T web ${COMMAND}
check-readme:
python -m readme_renderer README.md -o /tmp/README.html
diff --git a/README.md b/README.md
index ace2f3e..08f0fbd 100644
--- a/README.md
+++ b/README.md
@@ -110,7 +110,7 @@ Note: `confirmation_fields` apply to both add/change confirmations.
**Confirm Action:**
```py
- from admin_confirm import AdminConfirmMixin
+ from admin_confirm import AdminConfirmMixin, confirm_action
class MyModelAdmin(AdminConfirmMixin, ModelAdmin):
actions = ["action1", "action2"]
diff --git a/admin_confirm/__init__.py b/admin_confirm/__init__.py
index f595caa..92c5748 100644
--- a/admin_confirm/__init__.py
+++ b/admin_confirm/__init__.py
@@ -1,2 +1,3 @@
-__all__ = ["admin"]
+__all__ = ["admin", "confirm_action"]
from .admin import AdminConfirmMixin # noqa
+from .admin import confirm_action # noqa
diff --git a/admin_confirm/admin.py b/admin_confirm/admin.py
index d87af26..759c8ed 100644
--- a/admin_confirm/admin.py
+++ b/admin_confirm/admin.py
@@ -1,3 +1,4 @@
+import functools
from typing import Dict
from django.contrib.admin.exceptions import DisallowedModelAdminToField
from django.contrib.admin.utils import flatten_fieldsets, unquote
@@ -5,11 +6,11 @@ from django.core.cache import cache
from django.core.exceptions import PermissionDenied
from django.template.response import TemplateResponse
from django.contrib.admin.options import TO_FIELD_VAR
-from django.utils.decorators import method_decorator
from django.utils.translation import gettext as _
from django.contrib.admin import helpers
from django.db.models import Model, ManyToManyField, FileField, ImageField
from django.forms import ModelForm
+from django.utils.decorators import method_decorator
from admin_confirm.utils import (
log,
get_admin_change_url,
@@ -433,6 +434,7 @@ class AdminConfirmMixin:
"app_label": opts.app_label,
"model_name": opts.model_name,
"opts": opts,
+ "obj": obj,
"changed_data": changed_data,
"add": add,
"save_as_new": SAVE_AS_NEW in request.POST,
@@ -454,6 +456,7 @@ def confirm_action(func):
return to the changelist without performing action.
"""
+ @functools.wraps(func)
def func_wrapper(modeladmin, request, queryset):
# First called by `Go` which would not have confirm_action in params
if request.POST.get("_confirm_action"):
diff --git a/admin_confirm/file_cache.py b/admin_confirm/file_cache.py
index 7baaeff..7df87ba 100644
--- a/admin_confirm/file_cache.py
+++ b/admin_confirm/file_cache.py
@@ -106,5 +106,9 @@ class FileCache(object):
def delete_all(self):
"Delete all cached file data from cache."
- self.cache.delete_many(self.cached_keys)
- self.cached_keys = []
+ # Issue #46 Redis Cache errs if we call delete_many with an empty list - fixed in Django 4.2
+ # Note: set_many() should check for empty data in redis too.
+ # See: https://github.com/django/django/commit/608ab043f75f1f9c094de57d2fd678f522bb8243
+ if self.cached_keys:
+ self.cache.delete_many(self.cached_keys)
+ self.cached_keys = []
diff --git a/admin_confirm/templates/admin/change_data.html b/admin_confirm/templates/admin/change_data.html
index da5d220..c9c3ebc 100644
--- a/admin_confirm/templates/admin/change_data.html
+++ b/admin_confirm/templates/admin/change_data.html
@@ -9,7 +9,7 @@
{% for field, values in changed_data.items %}
- | {{ field }} |
+ {% verbose_name obj field %} |
{{ values.0|format_change_data_field_value }} |
{{ values.1|format_change_data_field_value }} |
diff --git a/admin_confirm/templatetags/formatting.py b/admin_confirm/templatetags/formatting.py
index 2f579b4..499be63 100644
--- a/admin_confirm/templatetags/formatting.py
+++ b/admin_confirm/templatetags/formatting.py
@@ -17,3 +17,9 @@ def format_change_data_field_value(field_value):
return mark_safe(output)
except Exception:
return field_value
+
+
+@register.simple_tag
+def verbose_name(obj, fieldname):
+ if obj:
+ return obj._meta.get_field(fieldname).verbose_name
diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml
index 3641735..19dca11 100644
--- a/docker-compose.dev.yml
+++ b/docker-compose.dev.yml
@@ -9,7 +9,15 @@ services:
PYTHON_VERSION: "$PYTHON_VERSION"
DJANGO_VERSION: "$DJANGO_VERSION"
SELENIUM_VERSION: "$SELENIUM_VERSION"
- command: python tests/manage.py runserver 0.0.0.0:8000
+ # Note: collectstatic runs from inside the docker container and needs
+ # to access localstack through the host machine using host.docker.internal
+ # BUT when we access the django server from our host machine, we need to access
+ # the stored staticfiles via localhost, so export LOCALSTACK_HOST before and after
+ command: >
+ sh -c "export LOCALSTACK_HOST=host.docker.internal &&
+ python tests/manage.py collectstatic --no-input &&
+ export LOCALSTACK_HOST=localhost &&
+ python tests/manage.py runserver 0.0.0.0:8000"
volumes:
- .:/code
ports:
@@ -18,9 +26,8 @@ services:
- selenium
- localstack
environment:
- - SELENIUM_HOST=selenium
- # Used for localstack_client as well as our project
- LOCALSTACK_HOST=host.docker.internal
+ - SELENIUM_HOST=host.docker.internal
selenium:
image: selenium/standalone-firefox
@@ -32,8 +39,6 @@ services:
localstack:
image: localstack/localstack
- container_name: localstack_main
- network_mode: bridge
ports:
- "4566:4566"
- "4571:4571"
@@ -41,11 +46,11 @@ services:
- SERVICES=s3
- DEBUG=true
# enable persistance
- - DATA_DIR=/tmp/localstack/data
+ - PERSISTENCE=1
- LAMBDA_EXECUTOR=docker
- DOCKER_HOST=unix:///var/run/docker.sock
- HOSTNAME_EXTERNAL=localstack
volumes:
- "./docker-entrypoint-initaws.d:/docker-entrypoint-initaws.d"
- - "./tmp/localstack:/tmp/localstack"
+ - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
diff --git a/docs/development_process.md b/docs/development_process.md
index 2f9d064..92f05c8 100644
--- a/docs/development_process.md
+++ b/docs/development_process.md
@@ -4,15 +4,15 @@
_You can skip this and just use docker if you want_
Install pyenv
-pyenv install 3.8.0
+pyenv install 3.9.9
Create **virtualenv** via pyenv
```
-pyenv vituralenv 3.8.0 django-admin-confirm-3.8.0
+pyenv virtualenv 3.9.9 django-admin-confirm-3.9.9
```
-Now your terminal should have `(django-admin-confirm-3.8.0)` prefix, because `.python-version` should have auto switch your virtual env
+Now your terminal should have `(django-admin-confirm-3.9.9)` prefix, because `.python-version` should have auto switch your virtual env
Install requirements
@@ -63,15 +63,22 @@ from admin_confirm.utils import log
log('Message to send to stdout')
```
+**Localstack**:
+Localstack is used for integration testing and also in the test project.
+
+To check if localstack is running correctly, go to `http://localhost:4566`
+To check if the bucket has been set up correctly, go to `http://localhost:4566/mybucket`
+To check if the static files have been set up correctly, go to `http://localhost:4566/mybucket/static/admin/css/base.css`
+
**Docker:**
-Instead of local set-up, you can also use docker.
+Instead of local set-up, you can also use docker. You may have to delete `.python-version` to do this.
Install docker-compose (or Docker Desktop which installs this for you)
```
-docker-compose build
-docker-compose up -d
+docker-compose -f docker-compose.dev.yml build
+docker-compose -f docker-compose.dev.yml up -d
```
You should now be able to see the app running on `localhost:8000`
@@ -79,20 +86,22 @@ You should now be able to see the app running on `localhost:8000`
If you haven't already done migrations and created a superuser, you'll want to do it here
```
-docker-compose exec web tests/manage.py migrate
-docker-compose exec web tests/manage.py createsuperuser
+docker-compose -f docker-compose.dev.yml exec web tests/manage.py migrate
+docker-compose -f docker-compose.dev.yml exec web tests/manage.py createsuperuser
```
Running tests in docker:
```
-docker-compose exec -T web make test-all
+docker-compose -f docker-compose.dev.yml exec -T web make test-all
```
The integration tests are set up within docker. I recommend running the integration tests only in docker.
Docker is also set to mirror local folder so that you can edit code/tests and don't have to rebuild to run new code/tests.
+Use `docker-compose -f docker-compose.dev.yml up -d --force-recreate` if you need to restart the docker containers. For example when updating the docker-compose.yml file, but if you change `Dockerfile` you have to rebuild.
+
### Release process
Honestly this part is just for my reference. But who knows :) maybe we'll have another maintainer in the future.
@@ -100,7 +109,7 @@ Honestly this part is just for my reference. But who knows :) maybe we'll have a
Run tests, check coverage, check readme
```
-docker-compose exec -T web make test-all
+docker-compose -f docker-compose.dev.yml exec -T web make test-all
make check-readme
```
@@ -126,3 +135,5 @@ make run
```
Go on github and make a release in UI
+
+To update supported version badges, use https://shields.io
diff --git a/requirements.txt b/requirements.txt
index 12069d0..1ad54ec 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,6 +7,7 @@ readme-renderer~=28.0
twine~=3.3.0
coveralls~=3.0.0
Pillow~=8.1.0 # For ImageField
+wheel~=0.37.1
### SELENIUM ###
# Known issue: https://github.com/SeleniumHQ/selenium/issues/8762
@@ -18,7 +19,7 @@ selenium~=4.0.0.a5
### END SELENIUM ###
### S3 ###
-localstack~=0.12.9.1 # For testing with S3
+localstack~=1.0.0 # For testing with S3
django-storages~=1.11.1
-boto3~=1.17.47
+boto3>=1.20.0
### END S3 ###
diff --git a/setup.cfg b/setup.cfg
index 1664c2a..11c8fca 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -6,17 +6,26 @@ exclude =
admin_confirm/tests/*
tests/*
ignore =
- D107 # Missing docstring in init
- D400 # Doc-string: First line should end with a period
- C812 # missing trailing comma
- I001 # isort found an import in the wrong position
- I004 # sisort found an unexpected blank line in imports
- Q000 # Remove bad quotes
- WPS110 # Seems to require no one word variable names
- WPS305 # Found f string
- WPS336 # Explicit string concatination
+ # Missing docstring in init
+ D107
+ # Doc-string: First line should end with a period
+ D400
+ # missing trailing comma
+ C812
+ # isort found an import in the wrong position
+ I001
+ # isort found an unexpected blank line in imports
+ I004
+ # Remove bad quotes
+ Q000
+ # Seems to require no one word variable names
+ WPS110
+ # Found f string
+ WPS305
+ # Explicit string concatination
+ WPS336
per-file-ignores =
- admin_confirm/tests/*: D102, WPS118, WPS204
+admin_confirm/tests/*: D102, WPS118, WPS204
[coverage:run]
relative_files = True
omit = admin_confirm/tests/*
diff --git a/setup.py b/setup.py
index 11f3f46..c98003c 100644
--- a/setup.py
+++ b/setup.py
@@ -7,7 +7,7 @@ README = open(os.path.join(here, "README.md")).read()
setup(
name="django-admin-confirm",
- version="0.2.5",
+ version="1.0.0",
packages=["admin_confirm"],
description=("Adds confirmation to Django Admin changes, additions and actions"),
long_description_content_type="text/markdown",
@@ -17,9 +17,9 @@ setup(
url="https://github.com/trangpham/django-admin-confirm/",
license="Apache 2.0",
install_requires=[
- "Django>=2.2",
+ "Django>=3.2",
],
- python_requires=">=3",
+ python_requires=">=3.7",
project_urls={
"Release Notes": "https://github.com/TrangPham/django-admin-confirm/releases",
},
@@ -27,9 +27,8 @@ setup(
# list files in MANIFEST.in
include_package_data=True,
classifiers=[
- "Framework :: Django :: 2.2",
- "Framework :: Django :: 3.0",
- "Programming Language :: Python :: 3.6",
+ "Framework :: Django :: 3.2",
+ "Framework :: Django :: 4.0",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
diff --git a/tests/market/admin/checkout_admin.py b/tests/market/admin/checkout_admin.py
index ec5bd50..9f7a28d 100644
--- a/tests/market/admin/checkout_admin.py
+++ b/tests/market/admin/checkout_admin.py
@@ -1,5 +1,5 @@
from django.core.exceptions import ValidationError
-from admin_confirm.admin import AdminConfirmMixin
+from admin_confirm import AdminConfirmMixin
from django.contrib.admin import ModelAdmin
from django.forms import ModelForm
diff --git a/tests/market/admin/generalmanager_admin.py b/tests/market/admin/generalmanager_admin.py
index e346f82..59da468 100644
--- a/tests/market/admin/generalmanager_admin.py
+++ b/tests/market/admin/generalmanager_admin.py
@@ -1,6 +1,10 @@
from django.contrib.admin import ModelAdmin
+from admin_confirm.admin import AdminConfirmMixin
-class GeneralManagerAdmin(ModelAdmin):
+class GeneralManagerAdmin(AdminConfirmMixin, ModelAdmin):
save_as = True
search_fields = ["name"]
+ confirm_change = True
+ confirm_add = True
+ confirmation_fields = ["name", "headshot"]
diff --git a/tests/market/admin/shop_admin.py b/tests/market/admin/shop_admin.py
index 1589504..89ccd43 100644
--- a/tests/market/admin/shop_admin.py
+++ b/tests/market/admin/shop_admin.py
@@ -1,5 +1,5 @@
from django.contrib.admin import ModelAdmin
-from admin_confirm.admin import AdminConfirmMixin, confirm_action
+from admin_confirm import AdminConfirmMixin, confirm_action
class ShopAdmin(AdminConfirmMixin, ModelAdmin):
diff --git a/tests/market/apps.py b/tests/market/apps.py
deleted file mode 100644
index 0d79fee..0000000
--- a/tests/market/apps.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from django.apps import AppConfig
-
-
-class MarketConfig(AppConfig):
- name = "market"
diff --git a/tests/market/migrations/0013_auto_20210702_0041.py b/tests/market/migrations/0013_auto_20210702_0041.py
new file mode 100644
index 0000000..3a0fda5
--- /dev/null
+++ b/tests/market/migrations/0013_auto_20210702_0041.py
@@ -0,0 +1,28 @@
+# Generated by Django 3.2.5 on 2021-07-02 00:41
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('market', '0012_auto_20210326_0240'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='itemsale',
+ name='total',
+ field=models.DecimalField(decimal_places=2, max_digits=5),
+ ),
+ migrations.AlterField(
+ model_name='shoppingmall',
+ name='shops',
+ field=models.ManyToManyField(blank=True, to='market.Shop'),
+ ),
+ migrations.AlterField(
+ model_name='transaction',
+ name='total',
+ field=models.DecimalField(decimal_places=2, default=0, max_digits=5),
+ ),
+ ]
diff --git a/tests/market/migrations/0014_auto_20220413_0116.py b/tests/market/migrations/0014_auto_20220413_0116.py
new file mode 100644
index 0000000..728402c
--- /dev/null
+++ b/tests/market/migrations/0014_auto_20220413_0116.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.1.7 on 2022-04-13 01:16
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('market', '0013_auto_20210702_0041'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='shoppingmall',
+ name='general_manager',
+ field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='market.generalmanager', verbose_name='manager'),
+ ),
+ ]
diff --git a/tests/market/models.py b/tests/market/models.py
index 1b112cd..551b4a9 100644
--- a/tests/market/models.py
+++ b/tests/market/models.py
@@ -54,7 +54,7 @@ class ShoppingMall(models.Model):
name = models.CharField(max_length=120)
shops = models.ManyToManyField(Shop, blank=True)
general_manager = models.OneToOneField(
- GeneralManager, on_delete=models.CASCADE, null=True, blank=True
+ GeneralManager, on_delete=models.CASCADE, null=True, blank=True, verbose_name="manager"
)
town = models.ForeignKey(Town, on_delete=models.CASCADE, null=True, blank=True)
diff --git a/tests/test_project/settings/__init__.py b/tests/test_project/settings/__init__.py
index 5fa61d7..6b7a9bb 100644
--- a/tests/test_project/settings/__init__.py
+++ b/tests/test_project/settings/__init__.py
@@ -2,5 +2,5 @@
# And running the server are different
# (Possibly due to test_project being within a subfolder)
# This defaults settings to local unless
-# DJANGO_SETTINGS is specified.
+# DJANGO_SETTINGS_MODULE is specified.
from .local import *
diff --git a/tests/test_project/settings/base.py b/tests/test_project/settings/base.py
index 092a27f..51f6493 100644
--- a/tests/test_project/settings/base.py
+++ b/tests/test_project/settings/base.py
@@ -138,15 +138,17 @@ if USE_S3:
AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY", "test")
AWS_STORAGE_BUCKET_NAME = os.getenv("AWS_STORAGE_BUCKET_NAME", "mybucket")
AWS_DEFAULT_ACL = None
- AWS_S3_CUSTOM_DOMAIN = f"{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com"
+ # AWS_S3_CUSTOM_DOMAIN = f"{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com"
AWS_S3_OBJECT_PARAMETERS = {"CacheControl": "max-age=86400"}
# s3 static settings
- STATIC_LOCATION = "static"
- STATIC_URL = f"https://{AWS_S3_CUSTOM_DOMAIN}/{STATIC_LOCATION}/"
+ STATIC_LOCATION = "staticfiles"
+ STATIC_URL = f"{AWS_S3_ENDPOINT_URL}/{STATIC_LOCATION}/"
+ STATIC_ROOT = os.path.join(BASE_DIR, STATIC_LOCATION)
STATICFILES_STORAGE = "tests.storage_backends.StaticStorage"
# s3 public media settings
- PUBLIC_MEDIA_LOCATION = "media"
- MEDIA_URL = f"https://{AWS_S3_CUSTOM_DOMAIN}/{PUBLIC_MEDIA_LOCATION}/"
+ PUBLIC_MEDIA_LOCATION = "mediafiles"
+ MEDIA_URL = f"{AWS_S3_ENDPOINT_URL}/{PUBLIC_MEDIA_LOCATION}/"
+ MEDIA_ROOT = os.path.join(BASE_DIR, PUBLIC_MEDIA_LOCATION)
DEFAULT_FILE_STORAGE = "tests.storage_backends.PublicMediaStorage"
else:
STATIC_URL = "/staticfiles/"
@@ -155,3 +157,5 @@ else:
MEDIA_ROOT = os.path.join(BASE_DIR, "mediafiles")
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)
+
+DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
diff --git a/tests/test_project/settings/local.py b/tests/test_project/settings/local.py
index 865e254..b729df5 100644
--- a/tests/test_project/settings/local.py
+++ b/tests/test_project/settings/local.py
@@ -4,4 +4,6 @@ INSTALLED_APPS = INSTALLED_APPS + ["market"]
WSGI_APPLICATION = "test_project.wsgi.application"
ROOT_URLCONF = "test_project.urls"
-USE_S3 = "True"
+if USE_S3:
+ STATICFILES_STORAGE = "storage_backends.StaticStorage"
+ DEFAULT_FILE_STORAGE = "storage_backends.PublicMediaStorage"
diff --git a/tests/test_project/settings/test.py b/tests/test_project/settings/test.py
index 0bfa80b..8518949 100644
--- a/tests/test_project/settings/test.py
+++ b/tests/test_project/settings/test.py
@@ -3,5 +3,3 @@ from .base import *
INSTALLED_APPS = INSTALLED_APPS + ["tests.market"]
WSGI_APPLICATION = "tests.test_project.wsgi.application"
ROOT_URLCONF = "tests.test_project.urls"
-
-USE_S3 = "True"