Ticket #15089: 0001-Make-settings.SITE_ID-optional-for-django.contrib.si.patch

File 0001-Make-settings.SITE_ID-optional-for-django.contrib.si.patch, 6.4 KB (added by rm_, 5 years ago)

Avoid the domain, port split already handled by request.get_host(), better commit message

  • django/contrib/sites/models.py

    From 03c6356c38d9a103835226ad7db479168bef29ae Mon Sep 17 00:00:00 2001
    From: Riccardo Magliocchetti <riccardo.magliocchetti@gmail.com>
    Date: Thu, 3 Apr 2014 20:15:53 +0200
    Subject: [PATCH] Make settings.SITE_ID optional for django.contrib.sites
     #15089
    
    Using the request to do the Site matching.
    Based on patch from Claude Peroz.
    
    Signed-off-by: Riccardo Magliocchetti <riccardo.magliocchetti@gmail.com>
    ---
     django/contrib/sites/models.py    | 47 +++++++++++++++++++++++++--------------
     django/contrib/sites/shortcuts.py |  4 +++-
     django/contrib/sites/tests.py     | 11 +++++++++
     docs/ref/contrib/sites.txt        | 17 ++++++++++----
     4 files changed, 57 insertions(+), 22 deletions(-)
    
    diff --git a/django/contrib/sites/models.py b/django/contrib/sites/models.py
    index 0e80d91..ff9e9f2 100644
    a b def _simple_domain_name_validator(value): 
    3434
    3535class SiteManager(models.Manager):
    3636
    37     def get_current(self):
     37    def _get_site_by_id(self, sid):
     38        if not sid in SITE_CACHE:
     39            site = self.get(pk=sid)
     40            SITE_CACHE[sid] = site
     41        return SITE_CACHE[sid]
     42
     43    def _get_site_by_request(self, request):
     44        host = request.get_host()
     45        if not host in SITE_CACHE:
     46            site = self.get(domain__iexact=host)
     47            SITE_CACHE[host] = site
     48        return SITE_CACHE[host]
     49
     50    def get_current(self, request=None):
    3851        """
    3952        Returns the current ``Site`` based on the SITE_ID in the
    40         project's settings. The ``Site`` object is cached the first
    41         time it's retrieved from the database.
     53        project's settings if request is None. Otherwise return the
     54        the current ``Site`` matching its domain with request's host
     55        The ``Site`` object is cached the first time it's retrieved
     56        from the database.
    4257        """
    43         from django.conf import settings
    44         try:
    45             sid = settings.SITE_ID
    46         except AttributeError:
    47             raise ImproperlyConfigured(
    48                 "You're using the Django \"sites framework\" without having "
    49                 "set the SITE_ID setting. Create a site in your database and "
    50                 "set the SITE_ID setting to fix this error.")
    51         try:
    52             current_site = SITE_CACHE[sid]
    53         except KeyError:
    54             current_site = self.get(pk=sid)
    55             SITE_CACHE[sid] = current_site
    56         return current_site
     58        if request:
     59            return self._get_site_by_request(request)
     60        else:
     61            from django.conf import settings
     62            try:
     63                sid = settings.SITE_ID
     64            except AttributeError:
     65                raise ImproperlyConfigured(
     66                    "You're using the Django \"sites framework\" without having "
     67                    "set the SITE_ID setting. Create a site in your database and "
     68                    "set the SITE_ID setting to fix this error.")
     69            return self._get_site_by_id(sid)
    5770
    5871    def clear_cache(self):
    5972        """Clears the ``Site`` object cache."""
  • django/contrib/sites/shortcuts.py

    diff --git a/django/contrib/sites/shortcuts.py b/django/contrib/sites/shortcuts.py
    index c525948..ddff468 100644
    a b def get_current_site(request): 
    1212    # the Site models when django.contrib.sites isn't installed.
    1313    if apps.is_installed('django.contrib.sites'):
    1414        from .models import Site
    15         return Site.objects.get_current()
     15        from django.conf import settings
     16        req = None if hasattr(settings, 'SITE_ID') else request
     17        return Site.objects.get_current(req)
    1618    else:
    1719        from .requests import RequestSite
    1820        return RequestSite(request)
  • django/contrib/sites/tests.py

    diff --git a/django/contrib/sites/tests.py b/django/contrib/sites/tests.py
    index fadd4aa..7652c50 100644
    a b class SitesFrameworkTests(TestCase): 
    7171            self.assertIsInstance(site, RequestSite)
    7272            self.assertEqual(site.name, "example.com")
    7373
     74    @override_settings(SITE_ID='', ALLOWED_HOSTS=['example.com'])
     75    def test_get_current_site_no_site_id(self):
     76        request = HttpRequest()
     77        request.META = {
     78            "SERVER_NAME": "example.com",
     79            "SERVER_PORT": "80",
     80        }
     81        del settings.SITE_ID
     82        site = get_current_site(request)
     83        self.assertEqual(site.name, "example.com")
     84
    7485    def test_domain_name_with_whitespaces(self):
    7586        # Regression for #17320
    7687        # Domain names are not allowed contain whitespace characters
  • docs/ref/contrib/sites.txt

    diff --git a/docs/ref/contrib/sites.txt b/docs/ref/contrib/sites.txt
    index 7561d54..0cb7edf 100644
    a b The sites framework is mainly based on a simple model: 
    1818.. class:: models.Site
    1919
    2020    A model for storing the ``domain`` and ``name`` attributes of a Web site.
    21     The :setting:`SITE_ID` setting specifies the database ID of the
    22     :class:`~django.contrib.sites.models.Site` object (accessible using
    23     the automatically added ``id`` attribute) associated with that
    24     particular settings file.
    2521
    2622    .. attribute:: domain
    2723
    The sites framework is mainly based on a simple model: 
    3127
    3228        A human-readable "verbose" name for the Web site.
    3329
     30The :setting:`SITE_ID` setting specifies the database ID of the
     31:class:`~django.contrib.sites.models.Site` object associated with that
     32particular settings file. It is possible to omit it, but then the
     33:func:`~django.contrib.sites.shortcuts.get_current_site` function will always
     34try to get the current site by comparing the
     35:attr:`~django.contrib.sites.models.Site.domain` with the host name from
     36the :meth:`~django.http.HttpRequest.get_host` method.
     37
    3438How you use this is up to you, but Django uses it in a couple of ways
    3539automatically via simple conventions.
    3640
    model(s). It's a model :doc:`manager </topics/db/managers>` that 
    308312automatically filters its queries to include only objects associated
    309313with the current :class:`~django.contrib.sites.models.Site`.
    310314
     315.. admonition:: Mandatory SITE_ID
     316
     317    The ``CurrentSiteManager`` is only usable when the :setting:`SITE_ID`
     318    setting is defined in your settings.
     319
    311320Use :class:`~django.contrib.sites.managers.CurrentSiteManager` by adding it to
    312321your model explicitly. For example::
    313322
Back to Top