Repository: django-extensions/django-extensions
Pull request #1662 (2021-04-27 21:33:06)

Fix django.contrib.sites detection in set_default_site command when using AppConfig
The purpose of this pull request is to improve `django.contrib.sites` application detection in the `set_default_site` command. Currently the command depends on having the name hardcoded in `settings.INSTALLED_APPS`, which could lead to not being able to detect the application if it is installed through the AppConfig class/mechanism.

Instead of the simple string check, the changed implementation uses application registry.

While not something that is common (I literally found one project that listed the `django.contrib.sites.apps.SitesConfig` in its example config), the small fix I propose is probably more robust than the existing one.


Patch:
diff --git a/django_extensions/management/commands/set_default_site.py b/django_extensions/management/commands/set_default_site.py
index 295d0aad..1ea5fc27 100644
--- a/django_extensions/management/commands/set_default_site.py
+++ b/django_extensions/management/commands/set_default_site.py
@@ -3,6 +3,7 @@ import socket
 
 from django.conf import settings
 from django.core.management.base import BaseCommand, CommandError
+from django.apps import apps
 
 from django_extensions.management.utils import signalcommand
 
@@ -29,7 +30,7 @@ class Command(BaseCommand):
 
     @signalcommand
     def handle(self, *args, **options):
-        if 'django.contrib.sites' not in settings.INSTALLED_APPS:
+        if not apps.is_installed('django.contrib.sites'):
             raise CommandError('The sites framework is not installed.')
 
         from django.contrib.sites.models import Site
diff --git a/docs/permissions.rst b/docs/permissions.rst
index 9ae787b2..837e3412 100644
--- a/docs/permissions.rst
+++ b/docs/permissions.rst
@@ -10,7 +10,7 @@ query and limit access to certain views.
 
 Current Mixins
 ---------------------------------
-* *UserPermissionMixin* - A Class Based View mixin that limits the accessibility to the view based on the "owner" of the view.
+* *ModelUserFieldPermissionMixin* - A Class Based View mixin that limits the accessibility to the view based on the "owner" of the view.
 
 This will check if the currently logged in user (``self.request.user``) matches the owner of the model instance.
 By default, the "owner" will be called "user".
@@ -33,11 +33,11 @@ By default, the "owner" will be called "user".
 
    from django.views.generic import UpdateView
 
-   from django_extensions.auth.mixins import UserPermissionMixin
+   from django_extensions.auth.mixins import ModelUserFieldPermissionMixin
 
    from .models import MyModel
 
-   class MyModelUpdateView(UserPermissionMixin, UpdateView):
+   class MyModelUpdateView(ModelUserFieldPermissionMixin, UpdateView):
       model = MyModel
       template_name = 'mymodels/update.html'
       model_permission_user_field = 'author'


Test patch:
diff --git a/tests/management/commands/test_set_default_site.py b/tests/management/commands/test_set_default_site.py
index 5d4950b0..eb596d6d 100644
--- a/tests/management/commands/test_set_default_site.py
+++ b/tests/management/commands/test_set_default_site.py
@@ -82,3 +82,10 @@ class SetDefaultSiteTests(TestCase):
 
         self.assertEqual(result.name, 'example.com')
         self.assertEqual(result.domain, 'bar')
+
+    def test_should_not_raise_if_sites_installed_through_appconfig(self):
+        with self.modify_settings(INSTALLED_APPS={
+            'append': 'django.contrib.sites.apps.SitesConfig',
+            'remove': 'django.contrib.sites',
+        }):
+            call_command('set_default_site', '--name=foo', '--domain=foo.bar')