diff --git a/django/contrib/databrowse/datastructures.py b/django/contrib/databrowse/datastructures.py
index 4fcdba9..e4da894 100644
a
|
b
|
These classes are light wrappers around Django's database API that provide
|
3 | 3 | convenience functionality and permalink functions for the databrowse app. |
4 | 4 | """ |
5 | 5 | |
| 6 | from django.contrib.databrowse.util import quote, unquote |
6 | 7 | from django.db import models |
| 8 | from django.db.models.query import QuerySet |
7 | 9 | from django.utils import formats |
8 | 10 | from django.utils.text import capfirst |
9 | | from django.utils.encoding import smart_unicode, smart_str, iri_to_uri |
| 11 | from django.utils.encoding import smart_unicode, smart_str |
10 | 12 | from django.utils.safestring import mark_safe |
11 | | from django.db.models.query import QuerySet |
| 13 | |
12 | 14 | |
13 | 15 | EMPTY_VALUE = '(None)' |
14 | 16 | DISPLAY_SIZE = 100 |
15 | 17 | |
| 18 | |
16 | 19 | class EasyModel(object): |
17 | 20 | def __init__(self, site, model): |
18 | 21 | self.site = site |
… |
… |
class EasyModel(object):
|
56 | 59 | def fields(self): |
57 | 60 | return [EasyField(self, f) for f in (self.model._meta.fields + self.model._meta.many_to_many)] |
58 | 61 | |
| 62 | |
59 | 63 | class EasyField(object): |
60 | 64 | def __init__(self, easy_model, field): |
61 | 65 | self.model, self.field = easy_model, field |
… |
… |
class EasyField(object):
|
73 | 77 | elif self.field.rel: |
74 | 78 | return mark_safe('%s%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name)) |
75 | 79 | |
| 80 | |
76 | 81 | class EasyChoice(object): |
77 | 82 | def __init__(self, easy_model, field, value, label): |
78 | 83 | self.model, self.field = easy_model, field |
… |
… |
class EasyChoice(object):
|
82 | 87 | return smart_str(u'<EasyChoice for %s.%s>' % (self.model.model._meta.object_name, self.field.name)) |
83 | 88 | |
84 | 89 | def url(self): |
85 | | return mark_safe('%s%s/%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.field.name, iri_to_uri(self.value))) |
| 90 | return mark_safe('%s%s/%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.field.name, quote(self.value))) |
| 91 | |
86 | 92 | |
87 | 93 | class EasyInstance(object): |
88 | 94 | def __init__(self, easy_model, instance): |
… |
… |
class EasyInstance(object):
|
104 | 110 | return self.instance._get_pk_val() |
105 | 111 | |
106 | 112 | def url(self): |
107 | | return mark_safe('%s%s/%s/objects/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, iri_to_uri(self.pk()))) |
| 113 | return mark_safe('%s%s/%s/objects/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, quote(self.pk()))) |
108 | 114 | |
109 | 115 | def fields(self): |
110 | 116 | """ |
… |
… |
class EasyInstance(object):
|
130 | 136 | 'object_list': [EasyInstance(em, i) for i in getattr(self.instance, rel_object.get_accessor_name()).all()], |
131 | 137 | } |
132 | 138 | |
| 139 | |
133 | 140 | class EasyInstanceField(object): |
134 | 141 | def __init__(self, easy_model, instance, field): |
135 | 142 | self.model, self.field, self.instance = easy_model, field, instance |
… |
… |
class EasyInstanceField(object):
|
184 | 191 | if self.field.rel.to in self.model.model_list: |
185 | 192 | lst = [] |
186 | 193 | for value in self.values(): |
187 | | url = mark_safe('%s%s/%s/objects/%s/' % (self.model.site.root_url, m.model._meta.app_label, m.model._meta.module_name, iri_to_uri(value._get_pk_val()))) |
| 194 | url = mark_safe('%s%s/%s/objects/%s/' % (self.model.site.root_url, m.model._meta.app_label, m.model._meta.module_name, quote(value._get_pk_val()))) |
188 | 195 | lst.append((smart_unicode(value), url)) |
189 | 196 | else: |
190 | 197 | lst = [(value, None) for value in self.values()] |
191 | 198 | elif self.field.choices: |
192 | 199 | lst = [] |
193 | 200 | for value in self.values(): |
194 | | url = mark_safe('%s%s/%s/fields/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name, iri_to_uri(self.raw_value))) |
| 201 | url = mark_safe('%s%s/%s/fields/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name, quote(self.raw_value))) |
195 | 202 | lst.append((value, url)) |
196 | 203 | elif isinstance(self.field, models.URLField): |
197 | 204 | val = self.values()[0] |
198 | | lst = [(val, iri_to_uri(val))] |
| 205 | lst = [(val, quote(val))] |
199 | 206 | else: |
200 | 207 | lst = [(self.values()[0], None)] |
201 | 208 | return lst |
202 | 209 | |
| 210 | |
203 | 211 | class EasyQuerySet(QuerySet): |
204 | 212 | """ |
205 | 213 | When creating (or cloning to) an `EasyQuerySet`, make sure to set the |
diff --git a/django/contrib/databrowse/plugins/fieldchoices.py b/django/contrib/databrowse/plugins/fieldchoices.py
index e0c01e9..5450212 100644
a
|
b
|
from django import http
|
2 | 2 | from django.db import models |
3 | 3 | from django.contrib.databrowse.datastructures import EasyModel |
4 | 4 | from django.contrib.databrowse.sites import DatabrowsePlugin |
| 5 | from django.contrib.databrowse.util import unquote, quote |
5 | 6 | from django.shortcuts import render_to_response |
6 | 7 | from django.utils.text import capfirst |
7 | 8 | from django.utils.encoding import smart_str, force_unicode |
8 | 9 | from django.utils.safestring import mark_safe |
9 | | import urllib |
| 10 | |
10 | 11 | |
11 | 12 | class FieldChoicePlugin(DatabrowsePlugin): |
12 | 13 | def __init__(self, field_filter=None): |
… |
… |
class FieldChoicePlugin(DatabrowsePlugin):
|
39 | 40 | return [mark_safe(u'%s%s/%s/%s/' % ( |
40 | 41 | easy_instance_field.model.url(), |
41 | 42 | plugin_name, easy_instance_field.field.name, |
42 | | urllib.quote(field_value, safe='')))] |
| 43 | quote(field_value)))] |
43 | 44 | |
44 | 45 | def model_view(self, request, model_databrowse, url): |
45 | 46 | self.model, self.site = model_databrowse.model, model_databrowse.site |
… |
… |
class FieldChoicePlugin(DatabrowsePlugin):
|
65 | 66 | return render_to_response('databrowse/fieldchoice_homepage.html', {'root_url': self.site.root_url, 'model': easy_model, 'field_list': field_list}) |
66 | 67 | |
67 | 68 | def field_view(self, request, field, value=None): |
| 69 | value = unquote(value) |
68 | 70 | easy_model = EasyModel(self.site, self.model) |
69 | 71 | easy_field = easy_model.field(field.name) |
70 | 72 | if value is not None: |
diff --git a/django/contrib/databrowse/templates/databrowse/fieldchoice_list.html b/django/contrib/databrowse/templates/databrowse/fieldchoice_list.html
index bb60a0e..eccb5d1 100644
a
|
b
|
|
1 | 1 | {% extends "databrowse/base_site.html" %} |
| 2 | {% load databrowse %} |
2 | 3 | |
3 | 4 | {% block title %}{{ model.verbose_name_plural|capfirst }} by {{ field.field.verbose_name }}{% endblock %} |
4 | 5 | |
… |
… |
|
10 | 11 | |
11 | 12 | <ul class="objectlist"> |
12 | 13 | {% for object in object_list %} |
13 | | <li class="{% cycle 'odd' 'even' %}"><a href="{{ object|iriencode }}/">{{ object }}</a></li> |
| 14 | <li class="{% cycle 'odd' 'even' %}"><a href="{{ object|alternate_quote }}/">{{ object }}</a></li> |
14 | 15 | {% endfor %} |
15 | 16 | </ul> |
16 | 17 | |
diff --git a/django/contrib/databrowse/urls.py b/django/contrib/databrowse/urls.py
index 9b85d14..2559686 100644
a
|
b
|
|
1 | | from django.conf.urls.defaults import * |
| 1 | from django.conf.urls.defaults import patterns |
2 | 2 | from django.contrib.databrowse import views |
3 | 3 | |
4 | 4 | # Note: The views in this URLconf all require a 'models' argument, |