Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
.cache/
.eggs/
.installed.cfg
.idea
bin
develop-eggs
django_multisite.egg-info/
Expand All @@ -15,3 +16,5 @@ multisite/*.egg-info
.coverage
.tox/
.pytest_cache/
.env
build
6 changes: 6 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ Replace your SITE_ID in settings.py to::
from multisite import SiteID
SITE_ID = SiteID(default=1)

Beginning with django 3.2 the sites framework performs a check to ensure that :code:`SITE_ID` is an integer.
Add the following to the top of settings.py to use our check to allow integer or :code:`SiteID`::

from multisite import checks


Add these to your INSTALLED_APPS::

INSTALLED_APPS = [
Expand Down
5 changes: 2 additions & 3 deletions multisite/admin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
from __future__ import unicode_literals
from __future__ import absolute_import

from django.contrib import admin
from django.contrib.admin.views.main import ChangeList
from django.contrib.sites.models import Site
Expand All @@ -19,6 +16,7 @@ class AliasAdmin(admin.ModelAdmin):
readonly_fields = ('is_canonical',)
search_fields = ('domain',)


admin.site.register(Alias, AliasAdmin)


Expand All @@ -36,6 +34,7 @@ def get_queryset(self, request):
qs = qs.order_by(*ordering)
return qs


# HACK: Monkeypatch AliasInline into SiteAdmin
SiteAdmin.inlines = type(SiteAdmin.inlines)([AliasInline]) + SiteAdmin.inlines

Expand Down
20 changes: 20 additions & 0 deletions multisite/checks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from django.conf import settings
from django.contrib.sites import checks
from django.core.checks import Error

from . import SiteID


def check_site_id(app_configs, **kwargs):
""" Patch sites check because django 3.2 insists on an integer value for SITE_ID """
if (
hasattr(settings, 'SITE_ID') and
not isinstance(settings.SITE_ID, (type(None), int, SiteID))
):
return [
Error('The SITE_ID setting must be an integer or SiteID', id='sites.E101'),
]
return []


checks.check_site_id = check_site_id
4 changes: 0 additions & 4 deletions multisite/forms.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
from __future__ import unicode_literals
from __future__ import absolute_import


from django.contrib.sites.admin import SiteAdmin
from django.core.exceptions import ValidationError

Expand Down
3 changes: 0 additions & 3 deletions multisite/hacks.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
from __future__ import unicode_literals
from __future__ import absolute_import

import sys

from django.conf import settings
Expand Down
4 changes: 1 addition & 3 deletions multisite/hosts.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
from __future__ import unicode_literals
from __future__ import absolute_import

from django.utils.functional import empty, SimpleLazyObject


Expand Down Expand Up @@ -41,4 +38,5 @@ def __iter__(self):
for host in self.alias_model.objects.values_list('domain'):
yield host[0]


ALLOWED_HOSTS = IterableLazyObject(lambda: AllowedHosts())
4 changes: 0 additions & 4 deletions multisite/management/commands/update_public_suffix_list.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import absolute_import

import logging
import os
import tempfile
Expand Down
7 changes: 2 additions & 5 deletions multisite/managers.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
# -*- coding: utf-8 -*
from __future__ import unicode_literals
from __future__ import absolute_import

from django.db import models
from django.contrib.sites import managers
from django.db.models.fields import FieldDoesNotExist
from django.core.exceptions import FieldDoesNotExist
from django.db import models
from django.db.models.sql import constants


Expand Down
34 changes: 8 additions & 26 deletions multisite/middleware.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,29 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from __future__ import absolute_import

import os
import tempfile
try:
from urlparse import urlsplit, urlunsplit
except ImportError:
from urllib.parse import urlsplit, urlunsplit
from urllib.parse import urlsplit, urlunsplit

import django
from django.conf import settings
from django.contrib.sites.models import Site, SITE_CACHE
from django.core.exceptions import DisallowedHost
from django.core import mail

from django.core.cache import caches

try:
# Django > 1.10 uses MiddlewareMixin
from django.utils.deprecation import MiddlewareMixin
except ImportError:
MiddlewareMixin = object

from django.core.exceptions import ImproperlyConfigured

try:
from django.urls import get_callable
except ImportError:
# Django < 1.10 compatibility
from django.core.urlresolvers import get_callable

from django.urls import get_callable
from django.db.models.signals import pre_save, post_delete, post_init
from django.http import Http404, HttpResponsePermanentRedirect

from hashlib import md5 as md5_constructor

from django.utils.deprecation import MiddlewareMixin

from .models import Alias


class DynamicSiteMiddleware(MiddlewareMixin):
def __init__(self, *args, **kwargs):
super(DynamicSiteMiddleware, self).__init__(*args, **kwargs)
def __init__(self, get_response=None):
super().__init__(get_response)
if not hasattr(settings.SITE_ID, 'set'):
raise TypeError('Invalid type for settings.SITE_ID: %s' %
type(settings.SITE_ID).__name__)
Expand Down Expand Up @@ -222,8 +204,8 @@ def site_deleted_hook(self, *args, **kwargs):


class CookieDomainMiddleware(MiddlewareMixin):
def __init__(self, *args, **kwargs):
super(CookieDomainMiddleware, self).__init__(*args, **kwargs)
def __init__(self, get_response=None):
super().__init__(get_response)
self.depth = int(getattr(settings, 'MULTISITE_COOKIE_DOMAIN_DEPTH', 0))
if self.depth < 0:
raise ValueError(
Expand Down
19 changes: 19 additions & 0 deletions multisite/migrations/0002_auto_20210520_1618.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 2.2.23 on 2021-05-20 16:18

from django.db import migrations, models
import multisite.models


class Migration(migrations.Migration):

dependencies = [
('multisite', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='alias',
name='is_canonical',
field=models.BooleanField(default=None, editable=False, help_text='Does this domain name match the one in site?', null=True, validators=[multisite.models.validate_true_or_none], verbose_name='is canonical?'),
),
]
19 changes: 6 additions & 13 deletions multisite/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
from __future__ import unicode_literals
from __future__ import absolute_import

import operator
from functools import reduce

Expand All @@ -11,15 +8,10 @@
from django.db.models import Q
from django.db.models.signals import pre_save, post_save
from django.db.models.signals import post_migrate
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

from .hacks import use_framework_for_site_cache

try:
xrange
except NameError: # python3
xrange = range

_site_domain = Site._meta.get_field('domain')

Expand Down Expand Up @@ -85,7 +77,7 @@ def _expand_netloc(cls, host, port=None):
bits = host.split('.')

result = []
for i in xrange(0, (len(bits) + 1)):
for i in range(0, (len(bits) + 1)):
if i == 0:
host = '.'.join(bits[i:])
else:
Expand Down Expand Up @@ -149,7 +141,6 @@ def validate_true_or_none(value):
raise ValidationError(u'%r must be True or None' % value)


@python_2_unicode_compatible
class Alias(models.Model):
"""
Model for domain-name aliases for Site objects.
Expand All @@ -168,9 +159,11 @@ class Alias(models.Model):
site = models.ForeignKey(
Site, related_name='aliases', on_delete=models.CASCADE
)
is_canonical = models.NullBooleanField(
is_canonical = models.BooleanField(
_('is canonical?'),
default=None, editable=False,
default=None,
editable=False,
null=True,
validators=[validate_true_or_none],
help_text=_('Does this domain name match the one in site?'),
)
Expand Down
15 changes: 5 additions & 10 deletions multisite/template/loaders/filesystem.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from __future__ import absolute_import

import os

from django.conf import settings
from django.contrib.sites.models import Site
from django.template.loaders.filesystem import Loader as FilesystemLoader
from django import VERSION as django_version


class Loader(FilesystemLoader):
def get_template_sources(self, *args, **kwargs):
template_name = args[0]
domain = Site.objects.get_current().domain
default_dir = getattr(settings, 'MULTISITE_DEFAULT_TEMPLATE_DIR',
'default')
default_dir = getattr(
settings, 'MULTISITE_DEFAULT_TEMPLATE_DIR', 'default'
)
for tname in (os.path.join(domain, template_name),
os.path.join(default_dir, template_name)):
if django_version < (2, 0, 0):
args = [tname, None]
else:
args = [tname]
args = [tname]
for item in super(Loader, self).get_template_sources(*args, **kwargs):
yield item
2 changes: 0 additions & 2 deletions multisite/template_loader.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from __future__ import absolute_import

from .template.loaders.filesystem import Loader

Expand Down
7 changes: 0 additions & 7 deletions multisite/test_settings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import django
from multisite import SiteID

SECRET_KEY = "iufoj=mibkpdz*%bob952x(%49rqgv8gg45k36kjcg76&-y5=!"
Expand All @@ -21,11 +20,5 @@
MIDDLEWARE = [
'multisite.middleware.DynamicSiteMiddleware',
]
if django.VERSION < (1,10,0):
# we are backwards compatible, but the settings file format has changed post-1.10:
# https://docs.djangoproject.com/en/1.10/topics/http/middleware/#upgrading-pre-django-1-10-style-middleware
MIDDLEWARE_CLASSES = list(MIDDLEWARE)
del MIDDLEWARE


TEST_RUNNER = 'django.test.runner.DiscoverRunner'
19 changes: 5 additions & 14 deletions multisite/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,27 @@

This file uses relative imports and so cannot be run standalone.
"""

from __future__ import unicode_literals
from __future__ import absolute_import

import django
import logging
import os
import pytest
import sys
import tempfile
import warnings
from unittest import skipUnless
from io import StringIO
from unittest import mock, skipUnless

try:
from unittest import mock
except ImportError:
import mock
from django.urls import re_path

from django.conf import settings
from django.conf.urls import url
from django.contrib.sites.models import Site
from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.core.management import call_command
from django.http import Http404, HttpResponse
from django.template.loader import get_template
from django.test import TestCase, override_settings
from django.test.client import RequestFactory as DjangoRequestFactory
from django.utils.six import StringIO

from multisite import SiteDomain, SiteID, threadlocals
from multisite import SiteDomain, SiteID

from .hacks import use_framework_for_site_cache
from .hosts import ALLOWED_HOSTS, AllowedHosts, IterableLazyObject
Expand Down Expand Up @@ -79,7 +70,7 @@ def test_get_current_site(self):
# So create one:
# (This is only used by test_integration)
urlpatterns = [
url(r'^domain/$', lambda request, *args, **kwargs: HttpResponse(str(Site.objects.get_current())))
re_path(r'^domain/$', lambda request, *args, **kwargs: HttpResponse(str(Site.objects.get_current())))
]

@pytest.mark.django_db
Expand Down
Loading