Skip to content

Commit

Permalink
Add TOKEN_MODEL setting
Browse files Browse the repository at this point in the history
Add SETTINGS_TO_IMPORT and _init_settings_to_import
Update {login|logout}_user with djoser.conf.settings.TOKEN_MODEL
Update TokenSerializer model with djoser.conf.settings.TOKEN_MODEL
Update docs to include information on TOKEN_MODEL
Update setting test for importable settings
  • Loading branch information
edelvalle authored and pszpetkowski committed Jul 7, 2017
1 parent 70f9bd2 commit d6a647f
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 7 deletions.
23 changes: 20 additions & 3 deletions djoser/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.test.signals import setting_changed
from django.utils import six
from django.utils.functional import LazyObject
from django.utils.module_loading import import_string


DJOSER_SETTINGS_NAMESPACE = 'DJOSER'
Expand All @@ -20,6 +21,7 @@
'PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND': False,
'ROOT_VIEW_URLS_MAPPING': {},
'PASSWORD_VALIDATORS': [],
'TOKEN_MODEL': 'rest_framework.authtoken.models.Token',
'SERIALIZERS': {
'activation': 'djoser.serializers.ActivationSerializer',
'login': 'djoser.serializers.LoginSerializer',
Expand All @@ -38,6 +40,8 @@
'USER_EMAIL_FIELD_NAME': 'email',
}

SETTINGS_TO_IMPORT = ['TOKEN_MODEL']


class Settings(object):
def __init__(self, default_settings, explicit_overriden_settings=None):
Expand All @@ -56,21 +60,34 @@ def __init__(self, default_settings, explicit_overriden_settings=None):
value.update(overriden_setting_value)
setattr(self, overriden_setting_name, value)

self._init_settings_to_import()

def _init_settings_to_import(self):
for setting_name in SETTINGS_TO_IMPORT:
value = getattr(self, setting_name)
setattr(self, setting_name, import_string(value))


class LazySettings(LazyObject):
def _setup(self, explicit_overriden_settings=None):
self._wrapped = Settings(default_settings, explicit_overriden_settings)

def get(self, key):
"""
This function is here only to provide backwards compatibility in case anyone uses old settings interface.
This function is here only to provide backwards compatibility in
case anyone uses old settings interface.
It is strongly encouraged to use dot notation.
"""
warnings.warn('The settings.get(key) is superseded by the dot attribute access.', PendingDeprecationWarning)
warnings.warn(
'The settings.get(key) is superseded by the dot attribute access.',
PendingDeprecationWarning
)
try:
return getattr(self, key)
except AttributeError:
raise ImproperlyConfigured('Missing settings: {}[\'{}\']'.format(DJOSER_SETTINGS_NAMESPACE, key))
raise ImproperlyConfigured('Missing settings: {}[\'{}\']'.format(
DJOSER_SETTINGS_NAMESPACE, key)
)


settings = LazySettings()
Expand Down
2 changes: 1 addition & 1 deletion djoser/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ class TokenSerializer(serializers.ModelSerializer):
auth_token = serializers.CharField(source='key')

class Meta:
model = Token
model = settings.TOKEN_MODEL
fields = (
'auth_token',
)
Expand Down
4 changes: 2 additions & 2 deletions djoser/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ def decode_uid(pk):


def login_user(request, user):
token, _ = authtoken.models.Token.objects.get_or_create(user=user)
token, _ = settings.TOKEN_MODEL.objects.get_or_create(user=user)
user_logged_in.send(sender=user.__class__, request=request, user=user)
return token


def logout_user(request):
authtoken.models.Token.objects.filter(user=request.user).delete()
settings.TOKEN_MODEL.objects.filter(user=request.user).delete()
user_logged_out.send(
sender=request.user.__class__, request=request, user=request.user
)
Expand Down
8 changes: 8 additions & 0 deletions docs/source/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ an email is registered in the system.

**Default**: ``False``

TOKEN_MODEL
-----------

Points to which token model should be used for authentication.

**Example**: ``'knox.models.AuthToken'``
**Default**: ``'rest_framework.authtoken.models.Token'``

SERIALIZERS
-----------

Expand Down
8 changes: 7 additions & 1 deletion testproject/testapp/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from django.test.testcases import SimpleTestCase
from django.test.utils import override_settings
from django.utils import six
from django.utils.module_loading import import_string
from djet import assertions, utils, restframework
from rest_framework import status, authtoken
from rest_framework.request import Request, override_method
Expand Down Expand Up @@ -876,7 +877,12 @@ def test_settings_should_be_default_if_no_djoser_attrib_in_django_settings(self)
del django_settings.DJOSER

for setting_name, setting_value in six.iteritems(default_settings):
self.assertEqual(setting_value, getattr(djoser_settings, setting_name))
overridden_value = getattr(djoser_settings, setting_name)
try:
self.assertEqual(setting_value, overridden_value)
except AssertionError:
setting_value = import_string(setting_value)
self.assertEqual(setting_value, overridden_value)

@override_settings(DJOSER=dict(settings.DJOSER, **{'USE_HTML_EMAIL_TEMPLATES': True}))
def test_djoser_simple_setting_overriden(self):
Expand Down

0 comments on commit d6a647f

Please sign in to comment.