Commit 3dcf2c04 authored by Bryan  BRANCOTTE's avatar Bryan BRANCOTTE
Browse files

extracting UserPreferencesAbstractModel so it can be used when user_model is redefined

parent e08640df
Pipeline #61263 passed with stage
in 42 seconds
...@@ -5,7 +5,7 @@ from django.utils.html import format_html ...@@ -5,7 +5,7 @@ from django.utils.html import format_html
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import ugettext from django.utils.translation import ugettext
from basetheme_bootstrap.user_preferences import get_user_preference_class from basetheme_bootstrap.user_preferences_utils import get_user_preference_class
class ViewOnSiteModelAdmin(admin.ModelAdmin): class ViewOnSiteModelAdmin(admin.ModelAdmin):
......
...@@ -4,7 +4,7 @@ from django.conf import settings ...@@ -4,7 +4,7 @@ from django.conf import settings
from django.core.cache import cache from django.core.cache import cache
from basetheme_bootstrap.templatetags.basetheme_bootstrap import basetheme_bootstrap_template_if_not_redefined from basetheme_bootstrap.templatetags.basetheme_bootstrap import basetheme_bootstrap_template_if_not_redefined
from basetheme_bootstrap.user_preferences import get_user_preferences_for_user from basetheme_bootstrap.user_preferences_utils import get_user_preferences_for_user
logger = logging.getLogger("basetheme_bootstrap") logger = logging.getLogger("basetheme_bootstrap")
......
...@@ -10,8 +10,8 @@ from django.core.exceptions import ValidationError ...@@ -10,8 +10,8 @@ from django.core.exceptions import ValidationError
from django.test import TestCase, RequestFactory, override_settings from django.test import TestCase, RequestFactory, override_settings
from django.urls import reverse from django.urls import reverse
from basetheme_bootstrap import user_preferences, tokens from basetheme_bootstrap import user_preferences_utils, tokens
from basetheme_bootstrap.user_preferences import get_user_preferences_for_user from basetheme_bootstrap.user_preferences_utils import get_user_preferences_for_user
class AboutPageTests(TestCase): class AboutPageTests(TestCase):
...@@ -510,19 +510,19 @@ class UserPreferencesTests(TestCase): ...@@ -510,19 +510,19 @@ class UserPreferencesTests(TestCase):
def test_when_enabled_that_it_works(self): def test_when_enabled_that_it_works(self):
if not getattr(settings, "BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED", False): if not getattr(settings, "BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED", False):
return return
self.assertIsNotNone(user_preferences.get_user_preference_class()) self.assertIsNotNone(user_preferences_utils.get_user_preference_class())
pref = user_preferences.get_user_preferences_for_user(self.user) pref = user_preferences_utils.get_user_preferences_for_user(self.user)
self.assertIsNotNone(pref) self.assertIsNotNone(pref)
default_pref = user_preferences.get_user_preferences_for_user(None) default_pref = user_preferences_utils.get_user_preferences_for_user(None)
self.assertIsNotNone(default_pref) self.assertIsNotNone(default_pref)
self.assertNotEqual(pref, default_pref) self.assertNotEqual(pref, default_pref)
def test_when_enabled_that_it_works_2(self): def test_when_enabled_that_it_works_2(self):
if not getattr(settings, "BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED", False): if not getattr(settings, "BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED", False):
return return
default_pref = user_preferences.get_user_preferences_for_user(None) default_pref = user_preferences_utils.get_user_preferences_for_user(None)
self.assertIsNotNone(default_pref) self.assertIsNotNone(default_pref)
pref = user_preferences.get_user_preferences_for_user(self.user) pref = user_preferences_utils.get_user_preferences_for_user(self.user)
self.assertIsNotNone(pref) self.assertIsNotNone(pref)
self.assertNotEqual(pref, default_pref) self.assertNotEqual(pref, default_pref)
...@@ -533,16 +533,16 @@ class UserPreferencesTests(TestCase): ...@@ -533,16 +533,16 @@ class UserPreferencesTests(TestCase):
pref.save() pref.save()
str(pref) str(pref)
default_pref = user_preferences.get_user_preferences_for_user(None) default_pref = user_preferences_utils.get_user_preferences_for_user(None)
self.assertIsNotNone(default_pref) self.assertIsNotNone(default_pref)
pref = user_preferences.get_user_preferences_for_user(self.user) pref = user_preferences_utils.get_user_preferences_for_user(self.user)
self.assertIsNotNone(pref) self.assertIsNotNone(pref)
self.assertNotEqual(pref, default_pref) self.assertNotEqual(pref, default_pref)
def test_only_one_default_pref(self): def test_only_one_default_pref(self):
if not getattr(settings, "BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED", False): if not getattr(settings, "BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED", False):
return return
pref = user_preferences.get_user_preferences_for_user(self.user) pref = user_preferences_utils.get_user_preferences_for_user(self.user)
pref.user = None pref.user = None
self.assertRaises(ValidationError, pref.save) self.assertRaises(ValidationError, pref.save)
...@@ -550,7 +550,7 @@ class UserPreferencesTests(TestCase): ...@@ -550,7 +550,7 @@ class UserPreferencesTests(TestCase):
get_user_preferences_for_user(AnonymousUser()) get_user_preferences_for_user(AnonymousUser())
def test_caching_disabled_status_when_it_is_the_case(self): def test_caching_disabled_status_when_it_is_the_case(self):
user_preferences.get_user_preference_class() user_preferences_utils.get_user_preference_class()
self.assertTrue( self.assertTrue(
cache.get("has_no_user_preferences_model", False) or cache.get("has_no_user_preferences_model", False) or
getattr(settings, "BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED", False) getattr(settings, "BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED", False)
...@@ -572,9 +572,9 @@ class SignUpTestsUserPrefDown(SignUpTests): ...@@ -572,9 +572,9 @@ class SignUpTestsUserPrefDown(SignUpTests):
'password2': "user@mp.comuser@mp.comuser@mp.comuser@mp.com", 'password2': "user@mp.comuser@mp.comuser@mp.comuser@mp.com",
'first_name': "user" 'first_name': "user"
}) })
user_preferences.get_user_preference_class() user_preferences_utils.get_user_preference_class()
user_preferences.get_user_preference_class() user_preferences_utils.get_user_preference_class()
user_preferences.get_user_preferences_for_user(get_user_model().objects.first()) user_preferences_utils.get_user_preferences_for_user(get_user_model().objects.first())
def setUp(self): def setUp(self):
cache.clear() cache.clear()
......
...@@ -8,37 +8,11 @@ from django.core.exceptions import ValidationError ...@@ -8,37 +8,11 @@ from django.core.exceptions import ValidationError
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _, ugettext from django.utils.translation import ugettext_lazy as _, ugettext
logger = logging.getLogger("basetheme_bootstrap") from basetheme_bootstrap import user_preferences_utils
def get_user_preference_class():
if cache.get("has_no_user_preferences_model", False):
return None
if not getattr(settings, "BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED", False):
cache.set("has_no_user_preferences_model", True, None)
return None
try:
return apps.get_model(
app_label=getattr(settings, "BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_LOCATION_APP", "your_app"),
model_name=getattr(settings, "BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_NAME", "UserPreferences"),
)
except LookupError as e:
logging.error("Either create the UserPreferences model, "
"or set BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED to False")
cache.set("has_no_user_preferences_model", True, None)
return None
def get_user_preferences_for_user(user):
if cache.get("has_no_user_preferences_model", False):
return None
klass = get_user_preference_class()
if klass is None:
return None
return klass.get_for_user(user=user)
logger = logging.getLogger("basetheme_bootstrap")
class UserPreferencesAbstractModel(models.Model): class UserPreferencesAbstractModel(user_preferences_utils.UserPreferencesAbstractModelWithUser):
class Meta: class Meta:
abstract = True abstract = True
...@@ -49,71 +23,4 @@ class UserPreferencesAbstractModel(models.Model): ...@@ -49,71 +23,4 @@ class UserPreferencesAbstractModel(models.Model):
null=True, null=True,
related_name="user_preferences", related_name="user_preferences",
help_text=_("Leave blank for default user") help_text=_("Leave blank for default user")
) )
\ No newline at end of file
@classmethod
def get_for_user(cls, user):
try:
pref = cls.objects.get(user=user)
except cls.MultipleObjectsReturned:
for p in cls.objects.filter(user=None)[1:]:
p.delete()
pref = cls.objects.get(user=user)
except TypeError:
return cls.get_for_user(None)
except cls.DoesNotExist:
try:
pref, _ = cls.objects.get_or_create(user=None)
except cls.MultipleObjectsReturned:
for p in cls.objects.filter(user=None)[1:]:
p.delete()
pref, _ = cls.objects.get(user=None)
if user is not None:
pref.pk = None
pref.id = None
pref.user = user
pref.save()
return pref
def full_clean(self, **kwargs):
# Checking for coherency on default preferences (user is None)
if self.user is None:
try:
default_pref = self.__class__.objects.get(user=None)
if default_pref.id != self.id:
raise ValidationError('Can\'t have more than one default preferences object, specify a user.')
except self.__class__.DoesNotExist:
pass
return super().full_clean(**kwargs)
def save(self, *args, **kwargs):
self.full_clean()
return super().save(*args, **kwargs)
def __str__(self):
return ugettext("Default preferences") if self.user is None else '%s (%s)' % (
self.user.username,
self._meta.verbose_name.title(),
)
@classmethod
def get_allowed_fields(cls):
if cls.preferences_groups is not None:
for group, fields in cls.preferences_groups.items():
for f in fields:
yield f
return
for field_name in [f.name for f in cls._meta.get_fields()]:
if field_name == "id" or field_name == "pk" or field_name == "user":
continue
yield field_name
@classmethod
@property
def preferences_groups(cls):
return None
@property
def preferences_groups_descriptions(self):
return {}
import logging
from django.apps import apps
from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.cache import cache
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import ugettext_lazy as _, ugettext
logger = logging.getLogger("basetheme_bootstrap")
def get_user_preference_class():
if cache.get("has_no_user_preferences_model", False):
return None
if not getattr(settings, "BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED", False):
cache.set("has_no_user_preferences_model", True, None)
return None
try:
return apps.get_model(
app_label=getattr(settings, "BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_LOCATION_APP", "your_app"),
model_name=getattr(settings, "BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_NAME", "UserPreferences"),
)
except LookupError as e:
logging.error("Either create the UserPreferences model, "
"or set BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED to False")
cache.set("has_no_user_preferences_model", True, None)
return None
def get_user_preferences_for_user(user):
if cache.get("has_no_user_preferences_model", False):
return None
klass = get_user_preference_class()
if klass is None:
return None
return klass.get_for_user(user=user)
class UserPreferencesAbstractModelWithUser(models.Model):
class Meta:
abstract = True
@classmethod
def get_for_user(cls, user):
try:
pref = cls.objects.get(user=user)
except cls.MultipleObjectsReturned:
for p in cls.objects.filter(user=None)[1:]:
p.delete()
pref = cls.objects.get(user=user)
except TypeError:
return cls.get_for_user(None)
except cls.DoesNotExist:
try:
pref, _ = cls.objects.get_or_create(user=None)
except cls.MultipleObjectsReturned:
for p in cls.objects.filter(user=None)[1:]:
p.delete()
pref, _ = cls.objects.get(user=None)
if user is not None:
pref.pk = None
pref.id = None
pref.user = user
pref.save()
return pref
def full_clean(self, **kwargs):
# Checking for coherency on default preferences (user is None)
if self.user is None:
try:
default_pref = self.__class__.objects.get(user=None)
if default_pref.id != self.id:
raise ValidationError('Can\'t have more than one default preferences object, specify a user.')
except self.__class__.DoesNotExist:
pass
return super().full_clean(**kwargs)
def save(self, *args, **kwargs):
self.full_clean()
return super().save(*args, **kwargs)
def __str__(self):
return ugettext("Default preferences") if self.user is None else '%s (%s)' % (
self.user.username,
self._meta.verbose_name.title(),
)
@classmethod
def get_allowed_fields(cls):
if cls.preferences_groups is not None:
for group, fields in cls.preferences_groups.items():
for f in fields:
yield f
return
for field_name in [f.name for f in cls._meta.get_fields()]:
if field_name == "id" or field_name == "pk" or field_name == "user":
continue
yield field_name
@classmethod
@property
def preferences_groups(cls):
return None
@property
def preferences_groups_descriptions(self):
return {}
...@@ -21,7 +21,7 @@ from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode ...@@ -21,7 +21,7 @@ from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.translation import ugettext from django.utils.translation import ugettext
from basetheme_bootstrap import tokens from basetheme_bootstrap import tokens
from basetheme_bootstrap import user_preferences from basetheme_bootstrap import user_preferences_utils
from basetheme_bootstrap.default_settings import is_validating_email from basetheme_bootstrap.default_settings import is_validating_email
from basetheme_bootstrap.forms import UserCreationFormWithMore, \ from basetheme_bootstrap.forms import UserCreationFormWithMore, \
MyUserChangeForm, UserDeleteForm MyUserChangeForm, UserDeleteForm
...@@ -217,7 +217,7 @@ def user_delete(request): ...@@ -217,7 +217,7 @@ def user_delete(request):
@login_required @login_required
def account_detail(request): def account_detail(request):
klass = user_preferences.get_user_preference_class() klass = user_preferences_utils.get_user_preference_class()
if klass is None: if klass is None:
form_prefs = None form_prefs = None
else: else:
......
...@@ -7,7 +7,7 @@ readme = open('README.rst').read() ...@@ -7,7 +7,7 @@ readme = open('README.rst').read()
setup( setup(
name='django-basetheme-bootstrap', name='django-basetheme-bootstrap',
version='0.2.60', version='0.2.61',
description='Django Basetheme Bootstrap', description='Django Basetheme Bootstrap',
long_description=readme, long_description=readme,
author='Bryan Brancotte', author='Bryan Brancotte',
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment