Merge branch 'master' into docs
[philo.git] / models / nodes.py
index a89d653..3f40205 100644 (file)
@@ -3,6 +3,7 @@ from django.contrib.contenttypes.models import ContentType
 from django.contrib.contenttypes import generic
 from django.contrib.sites.models import Site, RequestSite
 from django.http import HttpResponse, HttpResponseServerError, HttpResponseRedirect, Http404
 from django.contrib.contenttypes import generic
 from django.contrib.sites.models import Site, RequestSite
 from django.http import HttpResponse, HttpResponseServerError, HttpResponseRedirect, Http404
+from django.core.exceptions import ValidationError
 from django.core.servers.basehttp import FileWrapper
 from django.core.urlresolvers import resolve, clear_url_caches, reverse, NoReverseMatch
 from django.template import add_to_builtins as register_templatetags
 from django.core.servers.basehttp import FileWrapper
 from django.core.urlresolvers import resolve, clear_url_caches, reverse, NoReverseMatch
 from django.template import add_to_builtins as register_templatetags
@@ -73,7 +74,7 @@ class Node(TreeEntity):
                else:
                        domain = ""
                
                else:
                        domain = ""
                
-               if not path:
+               if not path or subpath == "/":
                        subpath = subpath[1:]
                
                return '%s%s%s%s' % (domain, root_url, path, subpath)
                        subpath = subpath[1:]
                
                return '%s%s%s%s' % (domain, root_url, path, subpath)
@@ -113,8 +114,8 @@ class View(Entity):
                
                try:
                        subpath = reverse(view_name, urlconf=self, args=args or [], kwargs=kwargs or {})
                
                try:
                        subpath = reverse(view_name, urlconf=self, args=args or [], kwargs=kwargs or {})
-               except NoReverseMatch:
-                       raise ViewCanNotProvideSubpath
+               except NoReverseMatch, e:
+                       raise ViewCanNotProvideSubpath(e.message)
                
                if node is not None:
                        return node.construct_url(subpath)
                
                if node is not None:
                        return node.construct_url(subpath)
@@ -218,22 +219,31 @@ class TargetURLModel(models.Model):
                
                try:
                        self.get_target_url()
                
                try:
                        self.get_target_url()
-               except NoReverseMatch, e:
+               except (NoReverseMatch, ViewCanNotProvideSubpath), e:
                        raise ValidationError(e.message)
                
                super(TargetURLModel, self).clean()
        
        def get_reverse_params(self):
                params = self.reversing_parameters
                        raise ValidationError(e.message)
                
                super(TargetURLModel, self).clean()
        
        def get_reverse_params(self):
                params = self.reversing_parameters
-               args = isinstance(params, list) and params or None
-               kwargs = isinstance(params, dict) and params or None
+               args = kwargs = None
+               if isinstance(params, list):
+                       args = params
+               elif isinstance(params, dict):
+                       # Convert unicode keys to strings for Python < 2.6.5. Compare
+                       # http://stackoverflow.com/questions/4598604/how-to-pass-unicode-keywords-to-kwargs
+                       kwargs = {}
+                       for key, val in params.items():
+                               if isinstance(key, unicode):
+                                       key = str(key)
+                               kwargs[key] = val
                return self.url_or_subpath, args, kwargs
        
        def get_target_url(self):
                node = self.target_node
                if node is not None and node.accepts_subpath and self.url_or_subpath:
                        if self.reversing_parameters is not None:
                return self.url_or_subpath, args, kwargs
        
        def get_target_url(self):
                node = self.target_node
                if node is not None and node.accepts_subpath and self.url_or_subpath:
                        if self.reversing_parameters is not None:
-                               view_name, args, kwargs = self.get_reversing_params()
+                               view_name, args, kwargs = self.get_reverse_params()
                                subpath = node.view.reverse(view_name, args=args, kwargs=kwargs)
                        else:
                                subpath = self.url_or_subpath
                                subpath = node.view.reverse(view_name, args=args, kwargs=kwargs)
                        else:
                                subpath = self.url_or_subpath
@@ -244,7 +254,7 @@ class TargetURLModel(models.Model):
                        return node.get_absolute_url()
                else:
                        if self.reversing_parameters is not None:
                        return node.get_absolute_url()
                else:
                        if self.reversing_parameters is not None:
-                               view_name, args, kwargs = self.get_reversing_params()
+                               view_name, args, kwargs = self.get_reverse_params()
                                return reverse(view_name, args=args, kwargs=kwargs)
                        return self.url_or_subpath
        target_url = property(get_target_url)
                                return reverse(view_name, args=args, kwargs=kwargs)
                        return self.url_or_subpath
        target_url = property(get_target_url)