kopia lustrzana https://github.com/wagtail/wagtail
RoutablePage: Change way URL resolver is created
Fixes #1168 Prevously, we looked up the URLs directly from the subpage_urls attribute and gave the value this returned to Djangos get_resolver function. get_resolver implements an infinite LRU cache so if this attribute was a property, every time a different instance of RoutablePage called it, a new item was added to the cache. This would repeat until the process was restarted or crashed. This commit makes defining subpage_urls as a property raise an error so this memory leak can't happen. The implementation was taken from #1161 to make it forwards-compatible. The changes are: - Added a new classmethod called get_resolver. This builds a RegexURLResolver itself and caches it on the class - No longer using Djangos get_resolver so url configs don't get cached twice - Added a new classmethod called get_subpage_urls. This can be overridden by subclasses to add more URLspull/1225/head
rodzic
b5a3821dfa
commit
8e7c9306ad
|
@ -3,8 +3,7 @@ from __future__ import unicode_literals
|
||||||
from six import string_types
|
from six import string_types
|
||||||
|
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.core.urlresolvers import get_resolver
|
from django.core.urlresolvers import RegexURLResolver
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
|
||||||
|
|
||||||
from wagtail.wagtailcore.models import Page
|
from wagtail.wagtailcore.models import Page
|
||||||
from wagtail.wagtailcore.url_routing import RouteResult
|
from wagtail.wagtailcore.url_routing import RouteResult
|
||||||
|
@ -18,28 +17,36 @@ class RoutablePageMixin(object):
|
||||||
#: Set this to a tuple of ``django.conf.urls.url`` objects.
|
#: Set this to a tuple of ``django.conf.urls.url`` objects.
|
||||||
subpage_urls = None
|
subpage_urls = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_subpage_urls(cls):
|
||||||
|
if cls.subpage_urls:
|
||||||
|
return cls.subpage_urls
|
||||||
|
|
||||||
|
return ()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_resolver(cls):
|
||||||
|
if '_routablepage_urlresolver' not in cls.__dict__:
|
||||||
|
subpage_urls = cls.get_subpage_urls()
|
||||||
|
cls._routablepage_urlresolver = RegexURLResolver(r'^/', subpage_urls)
|
||||||
|
|
||||||
|
return cls._routablepage_urlresolver
|
||||||
|
|
||||||
def reverse_subpage(self, name, args=None, kwargs=None):
|
def reverse_subpage(self, name, args=None, kwargs=None):
|
||||||
"""
|
"""
|
||||||
This method does the same job as Djangos' built in "urlresolvers.reverse()" function for subpage urlconfs.
|
This method does the same job as Djangos' built in
|
||||||
|
"urlresolvers.reverse()" function for subpage urlconfs.
|
||||||
"""
|
"""
|
||||||
args = args or []
|
args = args or []
|
||||||
kwargs = kwargs or {}
|
kwargs = kwargs or {}
|
||||||
|
|
||||||
if self.subpage_urls is None:
|
return self.get_resolver().reverse(name, *args, **kwargs)
|
||||||
raise ImproperlyConfigured("You must set 'subpage_urls' on " + type(self).__name__)
|
|
||||||
|
|
||||||
resolver = get_resolver(self.subpage_urls)
|
|
||||||
return resolver.reverse(name, *args, **kwargs)
|
|
||||||
|
|
||||||
def resolve_subpage(self, path):
|
def resolve_subpage(self, path):
|
||||||
"""
|
"""
|
||||||
This finds a view method/function from a URL path.
|
This finds a view method/function from a URL path.
|
||||||
"""
|
"""
|
||||||
if self.subpage_urls is None:
|
view, args, kwargs = self.get_resolver().resolve(path)
|
||||||
raise ImproperlyConfigured("You must set 'subpage_urls' on " + type(self).__name__)
|
|
||||||
|
|
||||||
resolver = get_resolver(self.subpage_urls)
|
|
||||||
view, args, kwargs = resolver.resolve(path)
|
|
||||||
|
|
||||||
# If view is a string, find it as an attribute of self
|
# If view is a string, find it as an attribute of self
|
||||||
if isinstance(view, string_types):
|
if isinstance(view, string_types):
|
||||||
|
|
Ładowanie…
Reference in New Issue