problems with money_maker.py
jhonvidal opened this issue · comments
doing tests in python 3.6 everything works correctly.
The problem happens when using python version 3.8.3 it throws the following error:
ValueError at /es/admin/medexample/product/
Can not add/substract money in different currencies.
Request Method: GET
Request URL: http://localhost:8000/es/admin/medexample/product/
Django Version: 3.0.7
Exception Type: ValueError
Exception Value:
Can not add/substract money in different currencies.
Exception Location: /home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/shop/money/money_maker.py in _assert_addable, line 220
Python Executable: /home/kira/.virtualenvs/vmedexample/bin/python
Python Version: 3.8.3
Python Path:
['/home/kira/Desarrollo/implementacion/medexample',
'/usr/lib/python38.zip',
'/usr/lib/python3.8',
'/usr/lib/python3.8/lib-dynload',
'/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages']
Server time: Mié, 17 Jun 2020 17:46:00 +0000
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/shop/money/money_maker.py in _assert_addable
return 10**CURRENCIES[cls._currency_code][1]
def _assert_addable(self, other):
if not other:
# so that we can add/substract zero or None to any currency
return self.__class__('0')
if self._currency_code != getattr(other, '_currency_code', None):
raise ValueError("Can not add/substract money in different currencies.") …
return other
def _assert_multipliable(self, other):
if hasattr(other, '_currency_code'):
raise ValueError("Can not multiply currencies.")
if isinstance(other, float):
▼ Local vars
Variable Value
other
Decimal('399.00')
self
MoneyInEUR('399.000')
It is a project started with "cookiecutter-django-shop",
with all the data loaded with proof.
The error comes out when trying to access:
"http://localhost:8000/es/admin/medexample/product/"
clarify that it ran with python version 3.8.3
Just tried to reproduce this. However, when I access the products list view, I never enter into method _assert_addable
, therefore I'm unsure, that your shop is set up the same way as the demo shop. Can you please recheck.
It is default setting with all default data using "cookiecutter-django-shop".
It is important to remember that in python 3.6 the same project works flawlessly.
The problem is when using python with version 3.8.3.
When trying to access several addresses the same error comes out, for example:
http://localhost:8000/en/catalog/
ValueError at /en/catalog/
Can not add/substract money in different currencies.
Request Method: GET
Request URL: http://localhost:8000/en/catalog/
Django Version: 3.0.7
Exception Type: ValueError
Exception Value:
Can not add/substract money in different currencies.
Exception Location: /home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/shop/money/money_maker.py in _assert_addable, line 220
Python Executable: /home/kira/.virtualenvs/vmedexample/bin/python
Python Version: 3.8.3
Python Path:
['/home/kira/Desarrollo/implementacion/medexample',
'/usr/lib/python38.zip',
'/usr/lib/python3.8',
'/usr/lib/python3.8/lib-dynload',
'/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages']
Server time: Wed, 17 Jun 2020 22:27:46 +0000
Traceback Switch to copy-and-paste view
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/core/handlers/exception.py in inner
response = get_response(request)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/core/handlers/base.py in _get_response
response = self.process_exception_by_middleware(e, request)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/core/handlers/base.py in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/cms/utils/decorators.py in inner
return func(request, *args, **kwargs)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/views/decorators/csrf.py in wrapped_view
return view_func(*args, **kwargs)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/views/generic/base.py in view
return self.dispatch(request, *args, **kwargs)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/rest_framework/views.py in dispatch
response = self.handle_exception(exc)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/rest_framework/views.py in handle_exception
self.raise_uncaught_exception(exc)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/rest_framework/views.py in raise_uncaught_exception
raise exc
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/rest_framework/views.py in dispatch
response = handler(request, *args, **kwargs)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/shop/views/catalog.py in get
response = self.list(request, *args, **kwargs)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/rest_framework/mixins.py in list
return self.get_paginated_response(serializer.data)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/rest_framework/serializers.py in data
ret = super().data
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/rest_framework/serializers.py in data
self._data = self.to_representation(self.instance)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/rest_framework/serializers.py in to_representation
return [
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/rest_framework/serializers.py in <listcomp>
self.child.to_representation(item) for item in iterable
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/rest_framework/serializers.py in to_representation
ret[field.field_name] = field.to_representation(attribute)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/rest_framework/fields.py in to_representation
return method(value)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/shop/serializers/bases.py in get_price
return '{:f}'.format(price)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/shop/money/money_maker.py in __format__
amount = Decimal.quantize(self, self._cents).__format__(specifier)
…
▶ Local vars
/usr/lib/python3.8/_pydecimal.py in quantize
if ans != self:
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/shop/money/money_maker.py in __eq__
other = self._assert_addable(other)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/shop/money/money_maker.py in _assert_addable
raise ValueError("Can not add/substract money in different currencies.")
…
▶ Local vars
http://localhost:8000/en/admin/medexample/product/ 👍
ValueError at /en/admin/medexample/product/
Can not add/substract money in different currencies.
Request Method: GET
Request URL: http://localhost:8000/en/admin/medexample/product/
Django Version: 3.0.7
Exception Type: ValueError
Exception Value:
Can not add/substract money in different currencies.
Exception Location: /home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/shop/money/money_maker.py in _assert_addable, line 220
Python Executable: /home/kira/.virtualenvs/vmedexample/bin/python
Python Version: 3.8.3
Python Path:
['/home/kira/Desarrollo/implementacion/medexample',
'/usr/lib/python38.zip',
'/usr/lib/python3.8',
'/usr/lib/python3.8/lib-dynload',
'/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages']
Server time: Wed, 17 Jun 2020 22:35:58 +0000
Error during template rendering
In template /home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/contrib/admin/templates/admin/base.html, error at line 62
Can not add/substract money in different currencies.
52 {% endblock %}
53 </div>
54 {% endif %}
55 {% endblock %}
56 {% block nav-global %}{% endblock %}
57 </div>
58 <!-- END Header -->
59 {% block breadcrumbs %}
60 <div class="breadcrumbs">
61 <a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
62 {% if title %} › {{ title }}{% endif %}
63 </div>
64 {% endblock %}
65 {% endif %}
66
67 {% block messages %}
68 {% if messages %}
69 <ul class="messagelist">{% for message in messages %}
70 <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message|capfirst }}</li>
71 {% endfor %}</ul>
72 {% endif %}
Traceback Switch to copy-and-paste view
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/db/models/options.py in get_field
return self.fields_map[field_name]
…
▶ Local vars
During handling of the above exception ('get_price'), another exception occurred:
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/contrib/admin/utils.py in lookup_field
f = _get_non_gfk_field(opts, name)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/contrib/admin/utils.py in _get_non_gfk_field
field = opts.get_field(name)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/db/models/options.py in get_field
raise FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name))
…
▶ Local vars
During handling of the above exception (Product has no field named 'get_price'), another exception occurred:
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/core/handlers/exception.py in inner
response = get_response(request)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/core/handlers/base.py in _get_response
response = self.process_exception_by_middleware(e, request)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/core/handlers/base.py in _get_response
response = response.render()
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/response.py in render
self.content = self.rendered_content
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/response.py in rendered_content
return template.render(context, self._request)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/backends/django.py in render
return self.template.render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in render
return self._render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in _render
return self.nodelist.render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in render
bit = node.render_annotated(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in render_annotated
return self.render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/loader_tags.py in render
return compiled_parent._render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in _render
return self.nodelist.render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in render
bit = node.render_annotated(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in render_annotated
return self.render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/loader_tags.py in render
return compiled_parent._render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in _render
return self.nodelist.render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in render
bit = node.render_annotated(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in render_annotated
return self.render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/loader_tags.py in render
return compiled_parent._render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in _render
return self.nodelist.render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in render
bit = node.render_annotated(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in render_annotated
return self.render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/loader_tags.py in render
result = block.nodelist.render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in render
bit = node.render_annotated(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in render_annotated
return self.render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/loader_tags.py in render
result = block.nodelist.render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in render
bit = node.render_annotated(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/base.py in render_annotated
return self.render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/contrib/admin/templatetags/base.py in render
return super().render(context)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/template/library.py in render
_dict = self.func(*resolved_args, **resolved_kwargs)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/contrib/admin/templatetags/admin_list.py in result_list
'results': list(results(cl)),
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/contrib/admin/templatetags/admin_list.py in results
yield ResultList(None, items_for_result(cl, res, None))
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/contrib/admin/templatetags/admin_list.py in __init__
super().__init__(*items)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/contrib/admin/templatetags/admin_list.py in items_for_result
f, attr, value = lookup_field(field_name, result, cl.model_admin)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/django/contrib/admin/utils.py in lookup_field
value = attr(obj)
…
▶ Local vars
/home/kira/Desarrollo/implementacion/medexample/medexample/admin.py in get_price
return str(obj.get_real_instance().get_price(None))
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/shop/money/money_maker.py in __str__
vals.update(amount=Decimal.__str__(Decimal.quantize(self, self._cents)))
…
▶ Local vars
/usr/lib/python3.8/_pydecimal.py in quantize
if ans != self:
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/shop/money/money_maker.py in __eq__
other = self._assert_addable(other)
…
▶ Local vars
/home/kira/.virtualenvs/vmedexample/lib/python3.8/site-packages/shop/money/money_maker.py in _assert_addable
raise ValueError("Can not add/substract money in different currencies.")
…
▶ Local vars
this is the configuration file settings.py:
"""
Django settings for medexample project.
For more information on this file, see
https://docs.djangoproject.com/en/stable/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/stable/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
from decimal import Decimal
import os
from django.urls import reverse_lazy
from django.utils.text import format_lazy
from django.utils.translation import ugettext_lazy as _
from cmsplugin_cascade.bootstrap4.mixins import BootstrapUtilities
from cmsplugin_cascade.extra_fields.config import PluginExtraFieldsConfig
SHOP_APP_LABEL = 'medexample'
BASE_DIR = os.path.dirname(__file__)
# Root directory for this django project
PROJECT_ROOT = os.path.abspath(os.path.join(BASE_DIR, os.path.pardir))
# Directory where working files, such as media and databases are kept
WORK_DIR = os.environ.get('DJANGO_WORKDIR', os.path.abspath(
os.path.join(PROJECT_ROOT, 'workdir')))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
ADMINS = [("John Doe", 'john@example.com')]
# SECURITY WARNING: in production, inject the secret key through the environment
SECRET_KEY = os.environ.get(
'DJANGO_SECRET_KEY', 'aClgyAEAH3CGIeMPmLRr0MiZLnkn5KFmKQxJP20BX9VkDjxQ7I7GLSoRWdTauUlZ')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
SITE_ID = 1
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# On Unix systems, a value of None will cause Django to use the same
# timezone as the operating system.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = 'UTC'
USE_THOUSAND_SEPARATOR = True
# Application definition
# replace django.contrib.auth.models.User by implementation
# allowing to login via email address
AUTH_USER_MODEL = 'email_auth.User'
AUTH_PASSWORD_VALIDATORS = [{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {
'min_length': 6,
}
}]
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
]
INSTALLED_APPS = [
'django.contrib.auth',
'email_auth',
'polymorphic',
# deprecated: 'djangocms_admin_style',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sitemaps',
'djangocms_text_ckeditor',
'django_select2',
'cmsplugin_cascade',
'cmsplugin_cascade.clipboard',
'cmsplugin_cascade.sharable',
'cmsplugin_cascade.extra_fields',
'cmsplugin_cascade.icon',
'cmsplugin_cascade.segmentation',
'cms_bootstrap',
'adminsortable2',
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'django_elasticsearch_dsl',
'django_fsm',
'fsm_admin',
'djng',
'cms',
'menus',
'treebeard',
'sass_processor',
'sekizai',
'django_filters',
'filer',
'easy_thumbnails',
'easy_thumbnails.optimize',
'parler',
'post_office',
'shop',
'medexample',
]
MIDDLEWARE = [
# 'django.middleware.cache.UpdateCacheMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'shop.middleware.CustomerMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.gzip.GZipMiddleware',
'cms.middleware.language.LanguageCookieMiddleware',
'cms.middleware.user.CurrentUserMiddleware',
'cms.middleware.page.CurrentPageMiddleware',
'cms.middleware.utils.ApphookReloadMiddleware',
'cms.middleware.toolbar.ToolbarMiddleware',
# 'django.middleware.cache.FetchFromCacheMiddleware',
]
ROOT_URLCONF = 'medexample.urls'
WSGI_APPLICATION = 'wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(WORK_DIR, 'db.sqlite3'),
}
}
# Internationalization
# https://docs.djangoproject.com/en/stable/topics/i18n/
LANGUAGE_CODE = 'es'
USE_I18N = True
LANGUAGES = [
('es', _("Spanish")),
('en', _("English")),
]
PARLER_DEFAULT_LANGUAGE = LANGUAGE_CODE
PARLER_LANGUAGES = {
1: [
{'code': 'es'},
{'code': 'en'},
],
'default': {
'fallbacks': ['es', 'en'],
},
}
CMS_LANGUAGES = {
'default': {
'fallbacks': ['es', 'en'],
'redirect_on_fallback': True,
'public': True,
'hide_untranslated': False,
},
1: [{
'public': True,
'code': 'es',
'hide_untranslated': False,
'name': 'Es',
'redirect_on_fallback': True,
}, {
'public': True,
'code': 'en',
'hide_untranslated': False,
'name': 'En',
'redirect_on_fallback': True,
}]
}
USE_L10N = True
USE_TZ = True
USE_X_FORWARDED_HOST = True
X_FRAME_OPTIONS = 'SAMEORIGIN'
# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = os.path.join(WORK_DIR, 'media')
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = '/media/'
# Absolute path to the directory that holds static files.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = os.getenv('DJANGO_STATIC_ROOT', os.path.join(WORK_DIR, 'static'))
# URL that handles the static files served from STATIC_ROOT.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
STATICFILES_FINDERS = [
# or 'django.contrib.staticfiles.finders.FileSystemFinder',
'medexample.finders.FileSystemFinder',
# or 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'medexample.finders.AppDirectoriesFinder',
'sass_processor.finders.CssFinder',
]
STATICFILES_DIRS = [
('node_modules', os.path.join(PROJECT_ROOT, 'node_modules')),
]
TEMPLATES = [{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'APP_DIRS': True,
'DIRS': [],
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.template.context_processors.csrf',
'django.template.context_processors.request',
'django.contrib.messages.context_processors.messages',
'sekizai.context_processors.sekizai',
'cms.context_processors.cms_settings',
'shop.context_processors.customer',
'shop.context_processors.shop_settings',
]
}
}, {
'BACKEND': 'post_office.template.backends.post_office.PostOfficeTemplates',
'APP_DIRS': True,
'DIRS': [],
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.template.context_processors.request',
]
}
}]
POST_OFFICE = {
'TEMPLATE_ENGINE': 'post_office',
}
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
},
'select2': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
}
}
############################################
# settings for caching and storing session data
REDIS_HOST = os.getenv('REDIS_HOST')
if REDIS_HOST:
SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS = {
'host': REDIS_HOST,
'port': 6379,
'db': 0,
'prefix': 'session-',
'socket_timeout': 1
}
CACHES['default'] = {
'BACKEND': 'redis_cache.RedisCache',
'LOCATION': 'redis://{}:6379/1'.format(REDIS_HOST),
}
CACHE_MIDDLEWARE_ALIAS = 'default'
CACHE_MIDDLEWARE_SECONDS = 3600
else:
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
SESSION_SAVE_EVERY_REQUEST = True
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'filters': {'require_debug_false': {'()': 'django.utils.log.RequireDebugFalse'}},
'formatters': {
'simple': {
'format': '[%(asctime)s %(module)s] %(levelname)s: %(message)s'
},
},
'handlers': {
'console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'simple',
},
},
'loggers': {
'django': {
'handlers': ['console'],
'level': 'INFO',
'propagate': True,
},
'post_office': {
'handlers': ['console'],
'level': 'WARNING',
'propagate': True,
},
},
}
SILENCED_SYSTEM_CHECKS = ['auth.W004']
FIXTURE_DIRS = [
os.path.join(WORK_DIR, 'fixtures'),
]
############################################
# settings for sending mail
EMAIL_HOST = os.getenv('DJANGO_EMAIL_HOST', 'localhost')
EMAIL_PORT = os.getenv('DJANGO_EMAIL_PORT', 25)
EMAIL_HOST_USER = os.getenv('DJANGO_EMAIL_USER', 'no-reply@localhost')
EMAIL_HOST_PASSWORD = os.getenv('DJANGO_EMAIL_PASSWORD', 'smtp-secret')
EMAIL_USE_TLS = bool(os.getenv('DJANGO_EMAIL_USE_TLS', '1'))
DEFAULT_FROM_EMAIL = os.getenv('DJANGO_EMAIL_FROM', 'no-reply@localhost')
EMAIL_REPLY_TO = os.getenv('DJANGO_EMAIL_REPLY_TO', 'info@localhost')
EMAIL_BACKEND = 'post_office.EmailBackend'
############################################
# settings for third party Django apps
NODE_MODULES_URL = STATIC_URL + 'node_modules/'
SASS_PROCESSOR_INCLUDE_DIRS = [
os.path.join(PROJECT_ROOT, 'node_modules'),
]
COERCE_DECIMAL_TO_STRING = True
FSM_ADMIN_FORCE_PERMIT = True
ROBOTS_META_TAGS = ('noindex', 'nofollow')
SERIALIZATION_MODULES = {'json': str('shop.money.serializers')}
############################################
# settings for django-restframework and plugins
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'shop.rest.money.JSONRenderer',
# can be disabled for production environments
'rest_framework.renderers.BrowsableAPIRenderer',
],
'DEFAULT_FILTER_BACKENDS': [
'django_filters.rest_framework.DjangoFilterBackend',
],
# 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
# 'PAGE_SIZE': 16,
}
REST_AUTH_SERIALIZERS = {
'LOGIN_SERIALIZER': 'shop.serializers.auth.LoginSerializer',
}
############################################
# settings for storing files and images
FILER_ADMIN_ICON_SIZES = ('16', '32', '48', '80', '128')
FILER_ALLOW_REGULAR_USERS_TO_ADD_ROOT_FOLDERS = True
FILER_DUMP_PAYLOAD = False
FILE_UPLOAD_MAX_MEMORY_SIZE = 5242880
THUMBNAIL_HIGH_RESOLUTION = False
THUMBNAIL_PRESERVE_EXTENSIONS = True
THUMBNAIL_PROCESSORS = (
'easy_thumbnails.processors.colorspace',
'easy_thumbnails.processors.autocrop',
'filer.thumbnail_processors.scale_and_crop_with_subject_location',
'easy_thumbnails.processors.filters',
)
############################################
# settings for django-cms and its plugins
CMS_TEMPLATES = [
('medexample/pages/default.html', _("Default Page")),
]
CMS_CACHE_DURATIONS = {
'content': 600,
'menus': 3600,
'permissions': 86400,
}
CMS_PERMISSION = True
CMS_PLACEHOLDER_CONF = {
'Breadcrumb': {
'plugins': ['BreadcrumbPlugin'],
'parent_classes': {'BreadcrumbPlugin': None},
},
'Commodity Details': {
'plugins': ['BootstrapContainerPlugin', 'BootstrapJumbotronPlugin'],
'parent_classes': {
'BootstrapContainerPlugin': None,
'BootstrapJumbotronPlugin': None,
},
},
'Main Content': {
'plugins': ['BootstrapContainerPlugin', 'BootstrapJumbotronPlugin'],
'parent_classes': {
'BootstrapContainerPlugin': None,
'BootstrapJumbotronPlugin': None,
'TextLinkPlugin': ['TextPlugin', 'AcceptConditionPlugin'],
},
},
'Static Footer': {
'plugins': ['BootstrapContainerPlugin', 'BootstrapJumbotronPlugin'],
'parent_classes': {
'BootstrapContainerPlugin': None,
'BootstrapJumbotronPlugin': None,
},
},
}
CMSPLUGIN_CASCADE_PLUGINS = [
'cmsplugin_cascade.bootstrap4',
'cmsplugin_cascade.segmentation',
'cmsplugin_cascade.generic',
'cmsplugin_cascade.icon',
'cmsplugin_cascade.leaflet',
'cmsplugin_cascade.link',
'shop.cascade',
]
CMSPLUGIN_CASCADE = {
'link_plugin_classes': [
'shop.cascade.plugin_base.CatalogLinkPluginBase',
'shop.cascade.plugin_base.CatalogLinkForm',
],
'alien_plugins': ['TextPlugin', 'TextLinkPlugin', 'AcceptConditionPlugin'],
'bootstrap4': {
'template_basedir': 'angular-ui/',
},
'plugins_with_extra_render_templates': {
'CustomSnippetPlugin': [
('shop/catalog/product-heading.html', _("Product Heading")),
('medexample/catalog/manufacturer-filter.html', _("Manufacturer Filter")),
],
# required to purchase real estate
'ShopAddToCartPlugin': [
(None, _("Default")),
('medexample/catalog/commodity-add2cart.html', _("Add Commodity to Cart")),
],
},
'plugins_with_sharables': {
'BootstrapImagePlugin': ['image_shapes', 'image_width_responsive', 'image_width_fixed',
'image_height', 'resize_options'],
'BootstrapPicturePlugin': ['image_shapes', 'responsive_heights', 'responsive_zoom', 'resize_options'],
},
'plugins_with_extra_fields': {
'BootstrapCardPlugin': PluginExtraFieldsConfig(),
'BootstrapCardHeaderPlugin': PluginExtraFieldsConfig(),
'BootstrapCardBodyPlugin': PluginExtraFieldsConfig(),
'BootstrapCardFooterPlugin': PluginExtraFieldsConfig(),
'SimpleIconPlugin': PluginExtraFieldsConfig(),
},
'plugins_with_extra_mixins': {
'BootstrapContainerPlugin': BootstrapUtilities(),
'BootstrapRowPlugin': BootstrapUtilities(BootstrapUtilities.paddings),
'BootstrapYoutubePlugin': BootstrapUtilities(BootstrapUtilities.margins),
'BootstrapButtonPlugin': BootstrapUtilities(BootstrapUtilities.floats),
},
'leaflet': {
'tilesURL': 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}',
'accessToken': 'pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw',
'apiKey': 'AIzaSyD71sHrtkZMnLqTbgRmY_NsO0A9l9BQmv4',
},
'bookmark_prefix': '/',
'segmentation_mixins': [
('shop.cascade.segmentation.EmulateCustomerModelMixin',
'shop.cascade.segmentation.EmulateCustomerAdminMixin'),
],
'allow_plugin_hiding': True,
'register_page_editor': True,
}
CKEDITOR_SETTINGS = {
'language': '{{ language }}',
'skin': 'moono-lisa',
'toolbar_CMS': [
['Undo', 'Redo'],
['cmsplugins', '-', 'ShowBlocks'],
['Format'],
['TextColor', 'BGColor', '-', 'PasteText', 'PasteFromWord'],
'/',
['Bold', 'Italic', 'Underline', 'Strike', '-',
'Subscript', 'Superscript', '-', 'RemoveFormat'],
['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
['HorizontalRule'],
['NumberedList', 'BulletedList', 'Outdent', 'Indent'],
['Table', 'Source']
],
'stylesSet': format_lazy('default:{}', reverse_lazy('admin:cascade_texteditor_config')),
}
CKEDITOR_SETTINGS_CAPTION = {
'language': '{{ language }}',
'skin': 'moono-lisa',
'height': 70,
'toolbar_HTMLField': [
['Undo', 'Redo'],
['Format', 'Styles'],
['Bold', 'Italic', 'Underline', '-', 'Subscript',
'Superscript', '-', 'RemoveFormat'],
['Source']
],
}
CKEDITOR_SETTINGS_DESCRIPTION = {
'language': '{{ language }}',
'skin': 'moono-lisa',
'height': 250,
'toolbar_HTMLField': [
['Undo', 'Redo'],
['cmsplugins', '-', 'ShowBlocks'],
['Format', 'Styles'],
['TextColor', 'BGColor', '-', 'PasteText', 'PasteFromWord'],
['Maximize', ''],
'/',
['Bold', 'Italic', 'Underline', '-', 'Subscript',
'Superscript', '-', 'RemoveFormat'],
['JustifyLeft', 'JustifyCenter', 'JustifyRight'],
['HorizontalRule'],
['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent'],
['Source']
],
}
SELECT2_CSS = 'node_modules/select2/dist/css/select2.min.css'
SELECT2_JS = 'node_modules/select2/dist/js/select2.min.js'
SELECT2_I18N_PATH = 'node_modules/select2/dist/js/i18n'
#############################################
# settings for full index text search
ELASTICSEARCH_HOST = os.getenv('ELASTICSEARCH_HOST', 'localhost')
ELASTICSEARCH_DSL = {
'default': {
'hosts': '{}:9200'.format(ELASTICSEARCH_HOST)
},
}
############################################
# settings for django-shop and its plugins
SHOP_VALUE_ADDED_TAX = Decimal(19)
SHOP_DEFAULT_CURRENCY = 'EUR'
SHOP_EDITCART_NG_MODEL_OPTIONS = "{updateOn: 'default blur', debounce: {'default': 2500, 'blur': 0}}"
SHOP_CART_MODIFIERS = [
'medexample.modifiers.PrimaryCartModifier',
'shop.modifiers.taxes.CartExcludedTaxModifier',
'medexample.modifiers.PostalShippingModifier',
'shop.payment.modifiers.PayInAdvanceModifier',
'shop.shipping.modifiers.SelfCollectionModifier',
]
SHOP_ORDER_WORKFLOWS = [
'shop.payment.workflows.ManualPaymentWorkflowMixin',
'shop.payment.workflows.CancelOrderWorkflowMixin',
'shop.shipping.workflows.PartialDeliveryWorkflowMixin',
]
SHOP_CASCADE_FORMS = {
'CustomerForm': 'medexample.forms.CustomerForm',
}
I just retested with version 3.8.1 and here everything works fine.
Closing because I can't reproduce. Feel free to reopen, if you found new evidence for a bug.
I can confirm,
Python 3.8.6, default settings
File "/home/darek/.local/share/virtualenvs/my-shop-OpEeVNpI/lib/python3.8/site-packages/shop/money/money_maker.py", line 220, in _assert_addable
raise ValueError("Can not add/substract money in different currencies.")
ValueError: Can not add/substract money in different currencies.
@darekmeco would you mind adding a unit test which reproduces this error on Python-3.8 but works on Python<=3.7?