Ticket #13559: sites_context_processor.diff

File sites_context_processor.diff, 14.7 KB (added by Christoph Schindler, 12 years ago)

Updated patch for r17913

  • docs/ref/contrib/sites.txt

     
    215215lawrence.com alerts." On LJWorld.com, the email has the subject "Thanks for
    216216subscribing to LJWorld.com alerts." Same goes for the email's message body.
    217217
    218 Note that an even more flexible (but more heavyweight) way of doing this would
    219 be to use Django's template system. Assuming Lawrence.com and LJWorld.com have
    220 different template directories (:setting:`TEMPLATE_DIRS`), you could simply farm out
    221 to the template system like so::
     218The current Site object is made available in the
     219:ref:`template context <ref-templates-api>` when you use
     220:class:`~django.template.context.RequestContext` and when your
     221:setting:`TEMPLATE_CONTEXT_PROCESSORS` setting contains
     222``"django.contrib.sites.context_processors.site"``, which is default.
    222223
     224Using template context, an even more flexible (but more heavyweight) way of
     225sending email-notifications would be to use Django's template system::
     226
    223227    from django.core.mail import send_mail
    224     from django.template import loader, Context
     228    from django.template import loader, RequestContext
    225229
    226230    def register_for_newsletter(request):
    227231        # Check form values, etc., and subscribe the user.
    228232        # ...
    229233
    230         subject = loader.get_template('alerts/subject.txt').render(Context({}))
    231         message = loader.get_template('alerts/message.txt').render(Context({}))
     234        subject_template = loader.get_template('alerts/subject.txt')
     235        subject = subject_template.render(RequestContext(request, {}))
     236        message_template = loader.get_template('alerts/message.txt')
     237        message = message_template.render(RequestContext(request, {}))
    232238        send_mail(subject, message, 'editor@ljworld.com', [user.email])
    233239
    234240        # ...
    235241
    236242In this case, you'd have to create :file:`subject.txt` and :file:`message.txt` template
    237 files for both the LJWorld.com and Lawrence.com template directories. That
     243files that include ``{{ site.name }}`` and ``{{ site.domain }}``. That
    238244gives you more flexibility, but it's also more complex.
    239245
    240246It's a good idea to exploit the :class:`~django.contrib.sites.models.Site`
     
    389395  checks the current :setting:`SITE_ID` in retrieving flatpages to display.
    390396
    391397* In the :mod:`syndication framework <django.contrib.syndication>`, the
    392   templates for ``title`` and ``description`` automatically have access to a
    393   variable ``{{ site }}``, which is the
    394   :class:`~django.contrib.sites.models.Site` object representing the current
    395   site. Also, the hook for providing item URLs will use the ``domain`` from
     398  hook for providing item URLs will use the ``domain`` from
    396399  the current :class:`~django.contrib.sites.models.Site` object if you don't
    397400  specify a fully-qualified domain.
    398401
  • django/conf/global_settings.py

     
    197197# only parameter and returns a dictionary to add to the context.
    198198TEMPLATE_CONTEXT_PROCESSORS = (
    199199    'django.contrib.auth.context_processors.auth',
     200    'django.contrib.sites.context_processors.site',
    200201    'django.core.context_processors.debug',
    201202    'django.core.context_processors.i18n',
    202203    'django.core.context_processors.media',
  • django/contrib/syndication/views.py

     
    137137
    138138        for item in self.__get_dynamic_attr('items', obj):
    139139            if title_tmp is not None:
    140                 title = title_tmp.render(RequestContext(request, {'obj': item, 'site': current_site}))
     140                title = title_tmp.render(RequestContext(request, {'obj': item}))
    141141            else:
    142142                title = self.__get_dynamic_attr('item_title', item)
    143143            if description_tmp is not None:
    144                 description = description_tmp.render(RequestContext(request, {'obj': item, 'site': current_site}))
     144                description = description_tmp.render(RequestContext(request, {'obj': item}))
    145145            else:
    146146                description = self.__get_dynamic_attr('item_description', item)
    147147            link = add_domain(
  • django/contrib/sites/tests/base.py

     
     1from django.conf import settings
     2from django.contrib.sites.models import Site, RequestSite, get_current_site
     3from django.core.exceptions import ObjectDoesNotExist
     4from django.http import HttpRequest
     5from django.test import TestCase
     6
     7
     8class SitesFrameworkTests(TestCase):
     9
     10    def setUp(self):
     11        Site(id=settings.SITE_ID, domain="example.com", name="example.com").save()
     12        self.old_Site_meta_installed = Site._meta.installed
     13        Site._meta.installed = True
     14
     15    def tearDown(self):
     16        Site._meta.installed = self.old_Site_meta_installed
     17
     18    def test_save_another(self):
     19        # Regression for #17415
     20        # On some backends the sequence needs reset after save with explicit ID.
     21        # Test that there is no sequence collisions by saving another site.
     22        Site(domain="example2.com", name="example2.com").save()
     23
     24    def test_site_manager(self):
     25        # Make sure that get_current() does not return a deleted Site object.
     26        s = Site.objects.get_current()
     27        self.assertTrue(isinstance(s, Site))
     28        s.delete()
     29        self.assertRaises(ObjectDoesNotExist, Site.objects.get_current)
     30
     31    def test_site_cache(self):
     32        # After updating a Site object (e.g. via the admin), we shouldn't return a
     33        # bogus value from the SITE_CACHE.
     34        site = Site.objects.get_current()
     35        self.assertEqual(u"example.com", site.name)
     36        s2 = Site.objects.get(id=settings.SITE_ID)
     37        s2.name = "Example site"
     38        s2.save()
     39        site = Site.objects.get_current()
     40        self.assertEqual(u"Example site", site.name)
     41
     42    def test_get_current_site(self):
     43        # Test that the correct Site object is returned
     44        request = HttpRequest()
     45        request.META = {
     46            "SERVER_NAME": "example.com",
     47            "SERVER_PORT": "80",
     48        }
     49        site = get_current_site(request)
     50        self.assertTrue(isinstance(site, Site))
     51        self.assertEqual(site.id, settings.SITE_ID)
     52
     53        # Test that an exception is raised if the sites framework is installed
     54        # but there is no matching Site
     55        site.delete()
     56        self.assertRaises(ObjectDoesNotExist, get_current_site, request)
     57
     58        # A RequestSite is returned if the sites framework is not installed
     59        Site._meta.installed = False
     60        site = get_current_site(request)
     61        self.assertTrue(isinstance(site, RequestSite))
     62        self.assertEqual(site.name, u"example.com")
  • django/contrib/sites/tests/__init__.py

     
     1from django.contrib.sites.tests.base import SitesFrameworkTests
     2from django.contrib.sites.tests.context_processors import ContextProcessorTest
     3from django.contrib.sites.tests.context_processors import RequestSiteContextTest
  • django/contrib/sites/tests/urls.py

     
     1from django.conf.urls.defaults import *
     2
     3urlpatterns = patterns('',
     4    (r'^context_processors/$', 'django.views.generic.simple.direct_to_template',
     5        {'template': 'sites/context_processors_test.html'}),
     6)
  • django/contrib/sites/tests/context_processors.py

     
     1import os
     2from django.test import TestCase
     3from django.conf import settings
     4from django.test.client import RequestFactory
     5from django.contrib.sites.models import Site, RequestSite
     6
     7class ContextProcessorTest(TestCase):
     8    urls = 'django.contrib.sites.tests.urls'
     9   
     10    def setUp(self):
     11        self.old_TEMPLATE_DIRS = settings.TEMPLATE_DIRS
     12        settings.TEMPLATE_DIRS = (
     13            os.path.join(
     14                os.path.dirname(__file__),
     15                'templates'
     16            ),
     17        )
     18   
     19    def tearDown(self):
     20        settings.TEMPLATE_DIRS = self.old_TEMPLATE_DIRS
     21   
     22    def test_context_processor(self):
     23        site_obj = Site.objects.get_current()
     24        response = self.client.get('/context_processors/')
     25        self.assertEqual(response.status_code, 200)
     26        self.assertContains(response, 'site.name: %s' % site_obj.name)
     27        self.assertContains(response, 'site.domain: %s' % site_obj.domain)
     28   
     29class RequestSiteContextTest(TestCase):
     30    urls = 'django.contrib.sites.tests.urls'
     31   
     32    def setUp(self):
     33        self.old_TEMPLATE_DIRS = settings.TEMPLATE_DIRS
     34        settings.TEMPLATE_DIRS = (
     35            os.path.join(
     36                os.path.dirname(__file__),
     37                'templates'
     38            ),
     39        )
     40        self.old_INSTALLED_APPS = settings.INSTALLED_APPS
     41        list_of_apps = list(settings.INSTALLED_APPS)
     42        list_of_apps.remove('django.contrib.sites')
     43        settings.INSTALLED_APPS = tuple(list_of_apps)
     44        self.factory = RequestFactory()
     45
     46    def tearDown(self):
     47        settings.TEMPLATE_DIRS = self.old_TEMPLATE_DIRS
     48        settings.INSTALLED_APPS = self.old_INSTALLED_APPS
     49
     50    def test_context_processor_without_sites_framework(self):
     51        request = self.factory.get('/context_processors/', SERVER_NAME='test.example.com')
     52        response = self.client.get(request.path, **request.META)
     53        site_obj = RequestSite(request)
     54        self.assertEqual(response.status_code, 200)
     55        self.assertContains(response, 'site.name: %s' % site_obj.name)
     56        self.assertContains(response, 'site.domain: %s' % site_obj.domain)
     57       
  • django/contrib/sites/tests/templates/sites/context_processors_test.html

     
     1site.name: {{ site.name }}
     2site.domain: {{ site.domain }}
  • django/contrib/sites/tests.py

     
    1 from django.conf import settings
    2 from django.contrib.sites.models import Site, RequestSite, get_current_site
    3 from django.core.exceptions import ObjectDoesNotExist
    4 from django.http import HttpRequest
    5 from django.test import TestCase
    6 
    7 
    8 class SitesFrameworkTests(TestCase):
    9 
    10     def setUp(self):
    11         Site(id=settings.SITE_ID, domain="example.com", name="example.com").save()
    12         self.old_Site_meta_installed = Site._meta.installed
    13         Site._meta.installed = True
    14 
    15     def tearDown(self):
    16         Site._meta.installed = self.old_Site_meta_installed
    17 
    18     def test_save_another(self):
    19         # Regression for #17415
    20         # On some backends the sequence needs reset after save with explicit ID.
    21         # Test that there is no sequence collisions by saving another site.
    22         Site(domain="example2.com", name="example2.com").save()
    23 
    24     def test_site_manager(self):
    25         # Make sure that get_current() does not return a deleted Site object.
    26         s = Site.objects.get_current()
    27         self.assertTrue(isinstance(s, Site))
    28         s.delete()
    29         self.assertRaises(ObjectDoesNotExist, Site.objects.get_current)
    30 
    31     def test_site_cache(self):
    32         # After updating a Site object (e.g. via the admin), we shouldn't return a
    33         # bogus value from the SITE_CACHE.
    34         site = Site.objects.get_current()
    35         self.assertEqual(u"example.com", site.name)
    36         s2 = Site.objects.get(id=settings.SITE_ID)
    37         s2.name = "Example site"
    38         s2.save()
    39         site = Site.objects.get_current()
    40         self.assertEqual(u"Example site", site.name)
    41 
    42     def test_get_current_site(self):
    43         # Test that the correct Site object is returned
    44         request = HttpRequest()
    45         request.META = {
    46             "SERVER_NAME": "example.com",
    47             "SERVER_PORT": "80",
    48         }
    49         site = get_current_site(request)
    50         self.assertTrue(isinstance(site, Site))
    51         self.assertEqual(site.id, settings.SITE_ID)
    52 
    53         # Test that an exception is raised if the sites framework is installed
    54         # but there is no matching Site
    55         site.delete()
    56         self.assertRaises(ObjectDoesNotExist, get_current_site, request)
    57 
    58         # A RequestSite is returned if the sites framework is not installed
    59         Site._meta.installed = False
    60         site = get_current_site(request)
    61         self.assertTrue(isinstance(site, RequestSite))
    62         self.assertEqual(site.name, u"example.com")
  • django/contrib/sites/context_processors.py

     
     1from django.contrib.sites.models import Site, RequestSite
     2from django.core.exceptions import ImproperlyConfigured
     3from django.db import models
     4
     5def site(request):
     6    """Sets in the present context information about the current site."""
     7    # CurrentSiteManager already handles prevention of spurious database calls
     8    # If the user does not have the Sites framework installed, for template
     9    # purposes, which will be read-only, a RequestSite object is an appropriate
     10    # fallback.
     11   
     12    try:
     13        site_app = models.get_app('sites')
     14        site_obj = Site.objects.get_current()
     15    except ImproperlyConfigured:
     16        site_obj = RequestSite(request)
     17    return {'site': site_obj}
  • django/contrib/auth/views.py

     
    6262    context = {
    6363        'form': form,
    6464        redirect_field_name: redirect_to,
    65         'site': current_site,
    6665        'site_name': current_site.name,
    6766    }
    6867    if extra_context is not None:
Back to Top