From 6c2faaceb0482267cec19da0ff432984028f9d0c Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Fri, 28 Sep 2012 20:10:22 +0200 Subject: [PATCH] Made more extensive use of get_current_site Refs #15089 --- django/contrib/comments/moderation.py | 4 +- django/contrib/contenttypes/tests.py | 5 +- .../flatpages/templatetags/flatpages.py | 7 ++- django/contrib/redirects/middleware.py | 6 ++- django/views/decorators/cache.py | 2 +- docs/ref/contrib/sites.txt | 53 +++++++------------ 6 files changed, 35 insertions(+), 42 deletions(-) diff --git a/django/contrib/comments/moderation.py b/django/contrib/comments/moderation.py index 9b206a5bad..6c56d7a8a5 100644 --- a/django/contrib/comments/moderation.py +++ b/django/contrib/comments/moderation.py @@ -62,7 +62,7 @@ from django.contrib.comments import signals from django.db.models.base import ModelBase from django.template import Context, loader from django.contrib import comments -from django.contrib.sites.models import Site +from django.contrib.sites.models import get_current_site from django.utils import timezone class AlreadyModerated(Exception): @@ -240,7 +240,7 @@ class CommentModerator(object): t = loader.get_template('comments/comment_notification_email.txt') c = Context({ 'comment': comment, 'content_object': content_object }) - subject = '[%s] New comment posted on "%s"' % (Site.objects.get_current().name, + subject = '[%s] New comment posted on "%s"' % (get_current_site(request).name, content_object) message = t.render(c) send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, recipient_list, fail_silently=True) diff --git a/django/contrib/contenttypes/tests.py b/django/contrib/contenttypes/tests.py index 2f92a34581..10311fae92 100644 --- a/django/contrib/contenttypes/tests.py +++ b/django/contrib/contenttypes/tests.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals from django.db import models from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.views import shortcut -from django.contrib.sites.models import Site +from django.contrib.sites.models import Site, get_current_site from django.http import HttpRequest, Http404 from django.test import TestCase from django.utils.http import urlquote @@ -219,9 +219,8 @@ class ContentTypesTests(TestCase): obj = FooWithUrl.objects.create(name="john") if Site._meta.installed: - current_site = Site.objects.get_current() response = shortcut(request, user_ct.id, obj.id) - self.assertEqual("http://%s/users/john/" % current_site.domain, + self.assertEqual("http://%s/users/john/" % get_current_site(request).domain, response._headers.get("location")[1]) Site._meta.installed = False diff --git a/django/contrib/flatpages/templatetags/flatpages.py b/django/contrib/flatpages/templatetags/flatpages.py index 702d968145..a32ac7f490 100644 --- a/django/contrib/flatpages/templatetags/flatpages.py +++ b/django/contrib/flatpages/templatetags/flatpages.py @@ -1,6 +1,7 @@ from django import template from django.conf import settings from django.contrib.flatpages.models import FlatPage +from django.contrib.sites.models import get_current_site register = template.Library() @@ -19,7 +20,11 @@ class FlatpageNode(template.Node): self.user = None def render(self, context): - flatpages = FlatPage.objects.filter(sites__id=settings.SITE_ID) + if 'request' in context: + site_pk = get_current_site(context['request']).pk + else: + site_pk = settings.SITE_ID + flatpages = FlatPage.objects.filter(sites__id=site_pk) # If a prefix was specified, add a filter if self.starts_with: flatpages = flatpages.filter( diff --git a/django/contrib/redirects/middleware.py b/django/contrib/redirects/middleware.py index 8998c2ce3e..927220d44d 100644 --- a/django/contrib/redirects/middleware.py +++ b/django/contrib/redirects/middleware.py @@ -1,4 +1,5 @@ from django.contrib.redirects.models import Redirect +from django.contrib.sites.models import get_current_site from django import http from django.conf import settings @@ -7,14 +8,15 @@ class RedirectFallbackMiddleware(object): if response.status_code != 404: return response # No need to check for a redirect for non-404 responses. path = request.get_full_path() + current_site = get_current_site(request) try: - r = Redirect.objects.get(site__id__exact=settings.SITE_ID, old_path=path) + r = Redirect.objects.get(site__id__exact=current_site.id, old_path=path) except Redirect.DoesNotExist: r = None if r is None and settings.APPEND_SLASH: # Try removing the trailing slash. try: - r = Redirect.objects.get(site__id__exact=settings.SITE_ID, + r = Redirect.objects.get(site__id__exact=current_site.id, old_path=path[:path.rfind('/')]+path[path.rfind('/')+1:]) except Redirect.DoesNotExist: pass diff --git a/django/views/decorators/cache.py b/django/views/decorators/cache.py index ac8b3752d7..06925c1f4a 100644 --- a/django/views/decorators/cache.py +++ b/django/views/decorators/cache.py @@ -12,7 +12,7 @@ def cache_page(*args, **kwargs): The cache is keyed by the URL and some data from the headers. Additionally there is the key prefix that is used to distinguish different cache areas in a multi-site setup. You could use the - sites.get_current().domain, for example, as that is unique across a Django + sites.get_current_site().domain, for example, as that is unique across a Django project. Additionally, all headers from the response's Vary header will be taken diff --git a/docs/ref/contrib/sites.txt b/docs/ref/contrib/sites.txt index 8bb7b27f32..790e003453 100644 --- a/docs/ref/contrib/sites.txt +++ b/docs/ref/contrib/sites.txt @@ -80,11 +80,11 @@ This accomplishes several things quite nicely: The view code that displays a given story just checks to make sure the requested story is on the current site. It looks something like this:: - from django.conf import settings + from django.contrib.sites.models import get_current_site def article_detail(request, article_id): try: - a = Article.objects.get(id=article_id, sites__id__exact=settings.SITE_ID) + a = Article.objects.get(id=article_id, sites__id__exact=get_current_site(request).id) except Article.DoesNotExist: raise Http404 # ... @@ -131,49 +131,36 @@ For example:: # Do something else. Of course, it's ugly to hard-code the site IDs like that. This sort of -hard-coding is best for hackish fixes that you need done quickly. A slightly +hard-coding is best for hackish fixes that you need done quickly. The cleaner way of accomplishing the same thing is to check the current site's domain:: - from django.conf import settings - from django.contrib.sites.models import Site + from django.contrib.sites.models import get_current_site def my_view(request): - current_site = Site.objects.get(id=settings.SITE_ID) + current_site = get_current_site(request) if current_site.domain == 'foo.com': # Do something else: # Do something else. -The idiom of retrieving the :class:`~django.contrib.sites.models.Site` object -for the value of :setting:`settings.SITE_ID ` is quite common, so -the :class:`~django.contrib.sites.models.Site` model's manager has a -``get_current()`` method. This example is equivalent to the previous one:: +This has also the advantage of checking if the sites framework is installed, and +return a :class:`RequestSite` instance if it is not. + +If you don't have access to the request object, you can use the +``get_current()`` method of the :class:`~django.contrib.sites.models.Site` +model's manager. You should then ensure that your settings file does contain +the :setting:`SITE_ID` setting. This example is equivalent to the previous one:: from django.contrib.sites.models import Site - def my_view(request): + def my_function_without_request(): current_site = Site.objects.get_current() if current_site.domain == 'foo.com': # Do something else: # Do something else. -For code which relies on getting the current domain but cannot be certain -that the sites framework will be installed for any given project, there is a -utility function :func:`~django.contrib.sites.models.get_current_site` that -takes a request object as an argument and returns either a Site instance (if -the sites framework is installed) or a RequestSite instance (if it is not). -This allows loose coupling with the sites framework and provides a usable -fallback for cases where it is not installed. - -.. function:: get_current_site(request) - - Checks if contrib.sites is installed and returns either the current - :class:`~django.contrib.sites.models.Site` object or a - :class:`~django.contrib.sites.models.RequestSite` object based on - the request. - Getting the current domain for display -------------------------------------- @@ -192,14 +179,14 @@ current site's :attr:`~django.contrib.sites.models.Site.name` and Here's an example of what the form-handling view looks like:: - from django.contrib.sites.models import Site + from django.contrib.sites.models import get_current_site from django.core.mail import send_mail def register_for_newsletter(request): # Check form values, etc., and subscribe the user. # ... - current_site = Site.objects.get_current() + current_site = get_current_site(request) send_mail('Thanks for subscribing to %s alerts' % current_site.name, 'Thanks for your subscription. We appreciate it.\n\n-The %s team.' % current_site.name, 'editor@%s' % current_site.domain, @@ -370,19 +357,19 @@ Here's how Django uses the sites framework: * In the :mod:`redirects framework `, each redirect object is associated with a particular site. When Django searches - for a redirect, it takes into account the current :setting:`SITE_ID`. + for a redirect, it takes into account the current site. * In the comments framework, each comment is associated with a particular site. When a comment is posted, its - :class:`~django.contrib.sites.models.Site` is set to the current - :setting:`SITE_ID`, and when comments are listed via the appropriate - template tag, only the comments for the current site are displayed. + :class:`~django.contrib.sites.models.Site` is set to the current site, + and when comments are listed via the appropriate template tag, only the + comments for the current site are displayed. * In the :mod:`flatpages framework `, each flatpage is associated with a particular site. When a flatpage is created, you specify its :class:`~django.contrib.sites.models.Site`, and the :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware` - checks the current :setting:`SITE_ID` in retrieving flatpages to display. + checks the current site in retrieving flatpages to display. * In the :mod:`syndication framework `, the templates for ``title`` and ``description`` automatically have access to a