Code

Ticket #15894: 15894_v2.diff

File 15894_v2.diff, 4.5 KB (added by krzysiumed, 3 years ago)
Line 
1diff --git a/django/contrib/sites/models.py b/django/contrib/sites/models.py
2index fecbff7..d5419f9 100644
3--- a/django/contrib/sites/models.py
4+++ b/django/contrib/sites/models.py
5@@ -1,8 +1,6 @@
6 from django.db import models
7 from django.utils.translation import ugettext_lazy as _
8-
9-
10-SITE_CACHE = {}
11+from django.core.cache import cache
12 
13 
14 class SiteManager(models.Manager):
15@@ -19,17 +17,17 @@ class SiteManager(models.Manager):
16         except AttributeError:
17             from django.core.exceptions import ImproperlyConfigured
18             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.")
19-        try:
20-            current_site = SITE_CACHE[sid]
21-        except KeyError:
22+
23+        current_site = cache.get('site-cache-%s' % sid)
24+        if current_site is None:
25             current_site = self.get(pk=sid)
26-            SITE_CACHE[sid] = current_site
27+            cache.set('site-cache-%s' % sid, current_site)
28         return current_site
29 
30     def clear_cache(self):
31         """Clears the ``Site`` object cache."""
32-        global SITE_CACHE
33-        SITE_CACHE = {}
34+        for s in self.all():
35+            cache.delete('site-cache-%s' % s.id)
36 
37 
38 class Site(models.Model):
39@@ -50,16 +48,12 @@ class Site(models.Model):
40     def save(self, *args, **kwargs):
41         super(Site, self).save(*args, **kwargs)
42         # Cached information will likely be incorrect now.
43-        if self.id in SITE_CACHE:
44-            del SITE_CACHE[self.id]
45+        cache.delete('site-cache-%s' % self.id)
46 
47     def delete(self):
48         pk = self.pk
49         super(Site, self).delete()
50-        try:
51-            del SITE_CACHE[pk]
52-        except KeyError:
53-            pass
54+        cache.delete('site-cache-%s' % self.id)
55 
56 
57 class RequestSite(object):
58diff --git a/docs/ref/contrib/sites.txt b/docs/ref/contrib/sites.txt
59index 8fc434b..7762eac 100644
60--- a/docs/ref/contrib/sites.txt
61+++ b/docs/ref/contrib/sites.txt
62@@ -178,6 +178,8 @@ fallback for cases where it is not installed.
63     :class:`~django.contrib.sites.models.RequestSite` object based on
64     the request.
65 
66+Note: ``get_current_site()`` and :attr:`~Site.objects.get_current()` use the cache backend specified in your CACHE_BACKEND setting.
67+
68 Getting the current domain for display
69 --------------------------------------
70 
71diff --git a/tests/regressiontests/sites_framework/tests.py b/tests/regressiontests/sites_framework/tests.py
72index 8e664fd..ee0f277 100644
73--- a/tests/regressiontests/sites_framework/tests.py
74+++ b/tests/regressiontests/sites_framework/tests.py
75@@ -1,5 +1,8 @@
76 from __future__ import absolute_import
77 
78+import time
79+from multiprocessing import Process, Queue, Value
80+
81 from django.conf import settings
82 from django.contrib.sites.models import Site
83 from django.test import TestCase
84@@ -36,3 +39,48 @@ class SitesFrameworkTestCase(TestCase):
85     def test_invalid_field_type(self):
86         article = ConfusedArticle.objects.create(title="More Bad News!", site=settings.SITE_ID)
87         self.assertRaises(TypeError, ConfusedArticle.on_site.all)
88+
89+    def test_multiprocess(self):
90+        def check_if_domain_changed(phase, domain_changed):
91+            from django.contrib.sites.models import Site
92+
93+            # first phase - get domain
94+            site = Site.objects.get_current()
95+            first_try = site.domain
96+            phase.value = 2
97+
98+            # second phase - wait
99+            while phase.value == 2:
100+                pass
101+
102+            # third phase - again get domain
103+            s2 = Site.objects.get_current()
104+            second_try = s2.domain
105+
106+            # compare domains
107+            domain_changed.value = (first_try != second_try)
108+
109+        def change_domain(phase):
110+            from django.contrib.sites.models import Site
111+
112+            # first phase - wait
113+            while phase.value == 1:
114+                pass
115+
116+            # second phase
117+            site = Site.objects.get_current()
118+            site.domain = site.domain+'_changed'
119+            site.save()
120+            phase.value = 3
121+
122+        phase = Value('i', 1)
123+        domain_changed = Value('b', False)
124+        first_process = Process(target=check_if_domain_changed, args=(phase, domain_changed))
125+        second_process = Process(target=change_domain, args=(phase,))
126+
127+        first_process.start()
128+        second_process.start()
129+        first_process.join()
130+        second_process.join()
131+
132+        self.assertTrue(domain_changed.value)