Ticket #15089: 15089-missing-site_id.diff

File 15089-missing-site_id.diff, 5.8 KB (added by Claude Paroz, 7 years ago)

get site from request when no SITE_ID

  • django/contrib/sites/models.py

    diff --git a/django/contrib/sites/models.py b/django/contrib/sites/models.py
    index 8590740..a7aa462 100644
    a b  
     1from django.core.exceptions import ImproperlyConfigured
    12from django.db import models
    23from django.utils.translation import ugettext_lazy as _
    34from django.utils.encoding import python_2_unicode_compatible
    SITE_CACHE = {} 
    89
    910class SiteManager(models.Manager):
    1011
     12    def _get_site_by_id(self, sid):
     13        if not sid in SITE_CACHE:
     14            site = self.get(pk=sid)
     15            SITE_CACHE[sid] = site
     16        return SITE_CACHE[sid]
     17
     18    def _get_site_by_request(self, request):
     19        host = request.get_host().lower()
     20        if ':' in host:
     21            host = host.split(':', 1)[0]
     22        if not host in SITE_CACHE:
     23            site = self.get(domain__iexact=host)
     24            SITE_CACHE[host] = site
     25        return SITE_CACHE[host]
     26
    1127    def get_current(self):
    1228        """
    1329        Returns the current ``Site`` based on the SITE_ID in the
    class SiteManager(models.Manager): 
    1834        try:
    1935            sid = settings.SITE_ID
    2036        except AttributeError:
    21             from django.core.exceptions import ImproperlyConfigured
    2237            raise ImproperlyConfigured("You're using the Django \"sites framework\" without having set the SITE_ID setting. Create a site in your database and set the SITE_ID setting to fix this error.")
    23         try:
    24             current_site = SITE_CACHE[sid]
    25         except KeyError:
    26             current_site = self.get(pk=sid)
    27             SITE_CACHE[sid] = current_site
    28         return current_site
     38        return self._get_site_by_id(sid)
    2939
    3040    def clear_cache(self):
    3141        """Clears the ``Site`` object cache."""
    def get_current_site(request): 
    92102    ``Site`` object or a ``RequestSite`` object based on the request.
    93103    """
    94104    if Site._meta.installed:
    95         current_site = Site.objects.get_current()
     105        from django.conf import settings
     106        if hasattr(settings, 'SITE_ID'):
     107            current_site = Site.objects.get_current()
     108        else:
     109            current_site = Site.objects._get_site_by_request(request)
    96110    else:
    97111        current_site = RequestSite(request)
    98112    return current_site
  • django/contrib/sites/tests.py

    diff --git a/django/contrib/sites/tests.py b/django/contrib/sites/tests.py
    index 1bb2495..28d8f26 100644
    a b from django.contrib.sites.models import Site, RequestSite, get_current_site 
    55from django.core.exceptions import ObjectDoesNotExist
    66from django.http import HttpRequest
    77from django.test import TestCase
     8from django.test.utils import override_settings
    89
    910
    1011class SitesFrameworkTests(TestCase):
    class SitesFrameworkTests(TestCase): 
    6263        site = get_current_site(request)
    6364        self.assertTrue(isinstance(site, RequestSite))
    6465        self.assertEqual(site.name, "example.com")
     66
     67    @override_settings(SITE_ID='')
     68    def test_get_current_site_no_site_id(self):
     69        request = HttpRequest()
     70        request.META = {
     71            "SERVER_NAME": "example.com",
     72            "SERVER_PORT": "80",
     73        }
     74        del settings.SITE_ID
     75        site = get_current_site(request)
     76        self.assertEqual(site.name, "example.com")
  • docs/ref/contrib/sites.txt

    diff --git a/docs/ref/contrib/sites.txt b/docs/ref/contrib/sites.txt
    index 790e003..05fe9c0 100644
    a b The whole sites framework is based on a simple model: 
    2020.. class:: Site
    2121
    2222    A model for storing the ``domain`` and ``name`` attributes of a Web site.
    23     The :setting:`SITE_ID` setting specifies the database ID of the
    24     :class:`~django.contrib.sites.models.Site` object associated with that
    25     particular settings file.
    2623
    2724    .. attribute:: domain
    2825
    The whole sites framework is based on a simple model: 
    3229
    3330        A human-readable "verbose" name for the Web site.
    3431
     32The :setting:`SITE_ID` setting specifies the database ID of the
     33:class:`~django.contrib.sites.models.Site` object associated with that
     34particular settings file. It is possible to omit it, but then you cannot
     35call the :meth:`~django.contrib.sites.models.Site.get_current` method any
     36more. The :func:`get_current_site` function will then always try to get the
     37current site by comparing the :attr:`~Site.domain` with the host name from the
     38:meth:`~django.http.HttpRequest.get_host` method.
    3539
    3640How you use this is up to you, but Django uses it in a couple of ways
    3741automatically via simple conventions.
    Caching the current ``Site`` object 
    244248===================================
    245249
    246250As the current site is stored in the database, each call to
    247 ``Site.objects.get_current()`` could result in a database query. But Django is a
    248 little cleverer than that: on the first request, the current site is cached, and
    249 any subsequent call returns the cached data instead of hitting the database.
     251``Site.objects.get_current()`` or to ``sites.get_current_site()`` could result
     252in a database query. But Django is a little cleverer than that: on the first
     253request, the current site is cached, and any subsequent call returns the cached
     254data instead of hitting the database.
    250255
    251256If for any reason you want to force a database query, you can tell Django to
    252257clear the cache using ``Site.objects.clear_cache()``::
    model(s). It's a model :doc:`manager </topics/db/managers>` that 
    277282automatically filters its queries to include only objects associated
    278283with the current :class:`~django.contrib.sites.models.Site`.
    279284
     285.. admonition:: Mandatory SITE_ID
     286
     287    The ``CurrentSiteManager`` is only usable when the :setting:`SITE_ID`
     288    setting is defined in your settings.
     289
    280290Use :class:`~django.contrib.sites.managers.CurrentSiteManager` by adding it to
    281291your model explicitly. For example::
    282292
Back to Top