Commit 12187bfd authored by Luke Plant's avatar Luke Plant
Browse files

[1.2.X] Fixed #14386, #8960, #10235, #10909, #10608, #13845, #14377 -...

[1.2.X] Fixed #14386, #8960, #10235, #10909, #10608, #13845, #14377 - standardize Site/RequestSite usage in various places.

Many thanks to gabrielhurley for putting most of this together.  Also to
bmihelac, arthurk, qingfeng, hvendelbo, petr.pulc@s-cape.cz, Hraban for
reports and some initial patches.

The patch also contains some whitespace/PEP8 fixes.

Backport of [13980] from trunk. Some items could be considered features
(i.e.  supporting RequestSite in various contrib apps), others are definite
bugs, but it was much more robust to backport all these tightly related
changes together.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@13987 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent c7ce5b89
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from django.contrib.auth.tokens import default_token_generator
from django.contrib.sites.models import Site
from django.contrib.sites.models import get_current_site
from django.template import Context, loader
from django import forms
from django.utils.translation import ugettext_lazy as _
@@ -117,14 +117,14 @@ class PasswordResetForm(forms.Form):
        return email

    def save(self, domain_override=None, email_template_name='registration/password_reset_email.html',
             use_https=False, token_generator=default_token_generator):
             use_https=False, token_generator=default_token_generator, request=None):
        """
        Generates a one-use only link for resetting password and sends to the user
        """
        from django.core.mail import send_mail
        for user in self.users_cache:
            if not domain_override:
                current_site = Site.objects.get_current()
                current_site = get_current_site(request)
                site_name = current_site.name
                domain = current_site.domain
            else:
+6 −0
Original line number Diff line number Diff line
@@ -249,6 +249,12 @@ class LogoutTest(AuthViewsTestCase):
        self.assert_('Logged out' in response.content)
        self.confirm_logged_out()

    def test_14377(self):
        # Bug 14377
        self.login()
        response = self.client.get('/logout/')
        self.assertTrue('site' in response.context)

    def test_logout_with_next_page_specified(self): 
        "Logout with next_page option given redirects to specified resource"
        self.login()
+16 −18
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ from django.contrib.auth.tokens import default_token_generator
from django.views.decorators.csrf import csrf_protect
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, get_object_or_404
from django.contrib.sites.models import Site, RequestSite
from django.contrib.sites.models import get_current_site
from django.http import HttpResponseRedirect, Http404
from django.template import RequestContext
from django.utils.http import urlquote, base36_to_int
@@ -54,10 +54,7 @@ def login(request, template_name='registration/login.html',

    request.session.set_test_cookie()

    if Site._meta.installed:
        current_site = Site.objects.get_current()
    else:
        current_site = RequestSite(request)
    current_site = get_current_site(request)

    return render_to_response(template_name, {
        'form': form,
@@ -75,7 +72,10 @@ def logout(request, next_page=None, template_name='registration/logged_out.html'
        if redirect_to:
            return HttpResponseRedirect(redirect_to)
        else:
            current_site = get_current_site(request)
            return render_to_response(template_name, {
                'site': current_site,
                'site_name': current_site.name,
                'title': _('Logged out')
            }, context_instance=RequestContext(request))
    else:
@@ -114,12 +114,10 @@ def password_reset(request, is_admin_site=False, template_name='registration/pas
            opts = {}
            opts['use_https'] = request.is_secure()
            opts['token_generator'] = token_generator
            opts['email_template_name'] = email_template_name
            opts['request'] = request
            if is_admin_site:
                opts['domain_override'] = request.META['HTTP_HOST']
            else:
                opts['email_template_name'] = email_template_name
                if not Site._meta.installed:
                    opts['domain_override'] = RequestSite(request).domain
            form.save(**opts)
            return HttpResponseRedirect(post_reset_redirect)
    else:
+59 −37
Original line number Diff line number Diff line
"""
Make sure that the content type cache (see ContentTypeManager) works correctly.
Lookups for a particular content type -- by model or by ID -- should hit the
database only on the first lookup.

First, let's make sure we're dealing with a blank slate (and that DEBUG is on so
that queries get logged)::

    >>> from django.conf import settings
    >>> settings.DEBUG = True

    >>> from django.contrib.contenttypes.models import ContentType
    >>> ContentType.objects.clear_cache()

    >>> from django import db
    >>> db.reset_queries()
from django import db
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site
from django.contrib.contenttypes.views import shortcut
from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpRequest
from django.test import TestCase

At this point, a lookup for a ContentType should hit the DB::

    >>> ContentType.objects.get_for_model(ContentType)
    <ContentType: content type>
class ContentTypesTests(TestCase):

    >>> len(db.connection.queries)
    1
    def setUp(self):
        # First, let's make sure we're dealing with a blank slate (and that
        # DEBUG is on so that queries get logged)
        self.old_DEBUG = settings.DEBUG
        self.old_Site_meta_installed = Site._meta.installed
        settings.DEBUG = True
        ContentType.objects.clear_cache()
        db.reset_queries()

A second hit, though, won't hit the DB, nor will a lookup by ID::
    def tearDown(self):
        settings.DEBUG = self.old_DEBUG
        Site._meta.installed = self.old_Site_meta_installed

    >>> ct = ContentType.objects.get_for_model(ContentType)
    >>> len(db.connection.queries)
    1
    >>> ContentType.objects.get_for_id(ct.id)
    <ContentType: content type>
    >>> len(db.connection.queries)
    1
    def test_lookup_cache(self):
        """
        Make sure that the content type cache (see ContentTypeManager)
        works correctly. Lookups for a particular content type -- by model or
        by ID -- should hit the database only on the first lookup.
        """

Once we clear the cache, another lookup will again hit the DB::
        # At this point, a lookup for a ContentType should hit the DB
        ContentType.objects.get_for_model(ContentType)
        self.assertEqual(1, len(db.connection.queries))

    >>> ContentType.objects.clear_cache()
    >>> ContentType.objects.get_for_model(ContentType)
    <ContentType: content type>
    >>> len(db.connection.queries)
    2
        # A second hit, though, won't hit the DB, nor will a lookup by ID
        ct = ContentType.objects.get_for_model(ContentType)
        self.assertEqual(1, len(db.connection.queries))
        ContentType.objects.get_for_id(ct.id)
        self.assertEqual(1, len(db.connection.queries))

Don't forget to reset DEBUG!
        # Once we clear the cache, another lookup will again hit the DB
        ContentType.objects.clear_cache()
        ContentType.objects.get_for_model(ContentType)
        len(db.connection.queries)
        self.assertEqual(2, len(db.connection.queries))

    >>> settings.DEBUG = False
    def test_shortcut_view(self):
        """
        Check that the shortcut view (used for the admin "view on site"
        functionality) returns a complete URL regardless of whether the sites
        framework is installed
        """

        request = HttpRequest()
        request.META = {
            "SERVER_NAME": "Example.com",
            "SERVER_PORT": "80",
        }
        from django.contrib.auth.models import User
        user_ct = ContentType.objects.get_for_model(User)
        obj = User.objects.create(username="john")
        Site._meta.installed = True
        response = shortcut(request, user_ct.id, obj.id)
        self.assertEqual("http://example.com/users/john/", response._headers.get("location")[1])
        Site._meta.installed = False
        response = shortcut(request, user_ct.id, obj.id)
        self.assertEqual("http://Example.com/users/john/", response._headers.get("location")[1])
+22 −20
Original line number Diff line number Diff line
from django import http
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site
from django.contrib.sites.models import Site, get_current_site
from django.core.exceptions import ObjectDoesNotExist

def shortcut(request, content_type_id, object_id):
@@ -26,6 +26,8 @@ def shortcut(request, content_type_id, object_id):
    # Otherwise, we need to introspect the object's relationships for a
    # relation to the Site object
    object_domain = None

    if Site._meta.installed:
        opts = obj._meta

        # First, look for an many-to-many relationship to Site.
@@ -54,7 +56,7 @@ def shortcut(request, content_type_id, object_id):
    # Fall back to the current site (if possible).
    if object_domain is None:
        try:
            object_domain = Site.objects.get_current().domain
            object_domain = get_current_site(request).domain
        except Site.DoesNotExist:
            pass

Loading