Sunday, December 30, 2018

Overriding settings in Django when used by the models


We are using Django for Speedy Net and Speedy Match (currently Django 1.11.17, we can't upgrade to a newer version of Django because of one of our requirements, django-modeltranslation). Some of our settings are used by the models. For example:

class USER_SETTINGS(object):      MIN_USERNAME_LENGTH = 6      MAX_USERNAME_LENGTH = 40        MIN_SLUG_LENGTH = 6      MAX_SLUG_LENGTH = 200        # Users can register from age 0 to 180, but can't be kept on the site after age 250.      MIN_AGE_ALLOWED_IN_MODEL = 0  # In years.      MAX_AGE_ALLOWED_IN_MODEL = 250  # In years.        MIN_AGE_ALLOWED_IN_FORMS = 0  # In years.      MAX_AGE_ALLOWED_IN_FORMS = 180  # In years.        MIN_PASSWORD_LENGTH = 8      MAX_PASSWORD_LENGTH = 120        MAX_NUMBER_OF_FRIENDS_ALLOWED = 800        PASSWORD_VALIDATORS = [          {              'NAME': 'speedy.core.accounts.validators.PasswordMinLengthValidator',          },          {              'NAME': 'speedy.core.accounts.validators.PasswordMaxLengthValidator',          },      ]

(which is defined in https://github.com/speedy-net/speedy-net/blob/uri_merge_with_master_2018-12-26_a/speedy/net/settings/global_settings.py). And then in the models I use:

from django.conf import settings as django_settings    class User(ValidateUserPasswordMixin, PermissionsMixin, Entity, AbstractBaseUser):      settings = django_settings.USER_SETTINGS

(and then use attributes of settings, such as settings.MIN_SLUG_LENGTH, in the class).

The problem is, when I try to override such settings in tests (you can see my question & answer on Can I define classes in Django settings, and how can I override such settings in tests?), User.settings remains the same and is not overridden by the settings I tried to override. This is a problem since in the model I passed settings.MIN_SLUG_LENGTH for example to validators, which are also passed other values by other models. Is it possible to define the models and settings in such a way which the correct settings will be used both in production and in tests, including when I want to override them?

I'm aware of this quote from https://docs.djangoproject.com/en/dev/topics/testing/tools/#overriding-settings:

Warning

The settings file contains some settings that are only consulted during initialization of Django internals. If you change them with override_settings, the setting is changed if you access it via the django.conf.settings module, however, Django's internals access it differently. Effectively, using override_settings() or modify_settings() with these settings is probably not going to do what you expect it to do.

We do not recommend altering the DATABASES setting. Altering the CACHES setting is possible, but a bit tricky if you are using internals that make using of caching, like django.contrib.sessions. For example, you will have to reinitialize the session backend in a test that uses cached sessions and overrides CACHES.

Finally, avoid aliasing your settings as module-level constants as override_settings() won't work on such values since they are only evaluated the first time the module is imported.

Which I understand are relevant in this case, but how do I define the settings in such a way that I can override them?

Thanks,
אורי (Uri)


אורי

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CABD5YeEpMnMAHiNOerSCni3hvntWWzBM7-QFkuZMDfDjsA%3Dx-Q%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment