~ubuntu-branches/ubuntu/quantal/python-django/quantal

« back to all changes in this revision

Viewing changes to django/contrib/admin/util.py

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb
  • Date: 2009-07-29 11:26:28 UTC
  • mfrom: (1.1.8 upstream) (4.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20090729112628-pg09ino8sz0sj21t
Tags: 1.1-1
* New upstream release.
* Merge from experimental:
  - Ship FastCGI initscript and /etc/default file in python-django's examples
    directory (Closes: #538863)
  - Drop "05_10539-sphinx06-compatibility.diff"; it has been applied
    upstream.
  - Bump Standards-Version to 3.8.2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
from django.utils.safestring import mark_safe
5
5
from django.utils.text import capfirst
6
6
from django.utils.encoding import force_unicode
7
 
from django.utils.translation import ugettext as _
8
 
 
 
7
from django.utils.translation import ungettext, ugettext as _
 
8
from django.core.urlresolvers import reverse, NoReverseMatch
9
9
 
10
10
def quote(s):
11
11
    """
61
61
        current = current[-1]
62
62
    current.append(val)
63
63
 
64
 
def get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current_depth, admin_site):
65
 
    "Helper function that recursively populates deleted_objects."
 
64
def get_change_view_url(app_label, module_name, pk, admin_site, levels_to_root):
 
65
    """
 
66
    Returns the url to the admin change view for the given app_label,
 
67
    module_name and primary key.
 
68
    """
 
69
    try:
 
70
        return reverse('%sadmin_%s_%s_change' % (admin_site.name, app_label, module_name), None, (pk,))
 
71
    except NoReverseMatch:
 
72
        return '%s%s/%s/%s/' % ('../'*levels_to_root, app_label, module_name, pk)
 
73
 
 
74
def get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current_depth, admin_site, levels_to_root=4):
 
75
    """
 
76
    Helper function that recursively populates deleted_objects.
 
77
 
 
78
    `levels_to_root` defines the number of directories (../) to reach the
 
79
    admin root path. In a change_view this is 4, in a change_list view 2.
 
80
 
 
81
    This is for backwards compatibility since the options.delete_selected
 
82
    method uses this function also from a change_list view.
 
83
    This will not be used if we can reverse the URL.
 
84
    """
66
85
    nh = _nest_help # Bind to local variable for performance
67
86
    if current_depth > 16:
68
87
        return # Avoid recursing too deep.
88
107
                if not has_admin:
89
108
                    # Don't display link to edit, because it either has no
90
109
                    # admin or is edited inline.
91
 
                    nh(deleted_objects, current_depth, [u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), sub_obj), []])
 
110
                    nh(deleted_objects, current_depth,
 
111
                        [u'%s: %s' % (capfirst(related.opts.verbose_name), force_unicode(sub_obj)), []])
92
112
                else:
93
113
                    # Display a link to the admin page.
94
 
                    nh(deleted_objects, current_depth, [mark_safe(u'%s: <a href="../../../../%s/%s/%s/">%s</a>' %
95
 
                        (escape(force_unicode(capfirst(related.opts.verbose_name))),
96
 
                            related.opts.app_label,
97
 
                            related.opts.object_name.lower(),
98
 
                            sub_obj._get_pk_val(), sub_obj)), []])
 
114
                    nh(deleted_objects, current_depth, [mark_safe(u'%s: <a href="%s">%s</a>' %
 
115
                        (escape(capfirst(related.opts.verbose_name)),
 
116
                        get_change_view_url(related.opts.app_label,
 
117
                                            related.opts.object_name.lower(),
 
118
                                            sub_obj._get_pk_val(),
 
119
                                            admin_site,
 
120
                                            levels_to_root),
 
121
                        escape(sub_obj))), []])
99
122
                get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2, admin_site)
100
123
        else:
101
124
            has_related_objs = False
104
127
                if not has_admin:
105
128
                    # Don't display link to edit, because it either has no
106
129
                    # admin or is edited inline.
107
 
                    nh(deleted_objects, current_depth, [u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), sub_obj), []])
 
130
                    nh(deleted_objects, current_depth,
 
131
                        [u'%s: %s' % (capfirst(related.opts.verbose_name), force_unicode(sub_obj)), []])
108
132
                else:
109
133
                    # Display a link to the admin page.
110
 
                    nh(deleted_objects, current_depth, [mark_safe(u'%s: <a href="../../../../%s/%s/%s/">%s</a>' % \
111
 
                        (escape(force_unicode(capfirst(related.opts.verbose_name))), related.opts.app_label, related.opts.object_name.lower(), sub_obj._get_pk_val(), escape(sub_obj))), []])
 
134
                    nh(deleted_objects, current_depth, [mark_safe(u'%s: <a href="%s">%s</a>' %
 
135
                        (escape(capfirst(related.opts.verbose_name)),
 
136
                        get_change_view_url(related.opts.app_label,
 
137
                                            related.opts.object_name.lower(),
 
138
                                            sub_obj._get_pk_val(),
 
139
                                            admin_site,
 
140
                                            levels_to_root),
 
141
                        escape(sub_obj))), []])
112
142
                get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2, admin_site)
113
143
            # If there were related objects, and the user doesn't have
114
144
            # permission to delete them, add the missing perm to perms_needed.
141
171
                    # Display a link to the admin page.
142
172
                    nh(deleted_objects, current_depth, [
143
173
                        mark_safe((_('One or more %(fieldname)s in %(name)s:') % {'fieldname': escape(force_unicode(related.field.verbose_name)), 'name': escape(force_unicode(related.opts.verbose_name))}) + \
144
 
                        (u' <a href="../../../../%s/%s/%s/">%s</a>' % \
145
 
                            (related.opts.app_label, related.opts.module_name, sub_obj._get_pk_val(), escape(sub_obj)))), []])
 
174
                        (u' <a href="%s">%s</a>' % \
 
175
                            (get_change_view_url(related.opts.app_label,
 
176
                                                 related.opts.object_name.lower(),
 
177
                                                 sub_obj._get_pk_val(),
 
178
                                                 admin_site,
 
179
                                                 levels_to_root),
 
180
                            escape(sub_obj)))), []])
146
181
        # If there were related objects, and the user doesn't have
147
182
        # permission to change them, add the missing perm to perms_needed.
148
183
        if has_admin and has_related_objs:
149
184
            p = u'%s.%s' % (related.opts.app_label, related.opts.get_change_permission())
150
185
            if not user.has_perm(p):
151
186
                perms_needed.add(related.opts.verbose_name)
 
187
 
 
188
def model_format_dict(obj):
 
189
    """
 
190
    Return a `dict` with keys 'verbose_name' and 'verbose_name_plural',
 
191
    typically for use with string formatting.
 
192
 
 
193
    `obj` may be a `Model` instance, `Model` subclass, or `QuerySet` instance.
 
194
 
 
195
    """
 
196
    if isinstance(obj, (models.Model, models.base.ModelBase)):
 
197
        opts = obj._meta
 
198
    elif isinstance(obj, models.query.QuerySet):
 
199
        opts = obj.model._meta
 
200
    else:
 
201
        opts = obj
 
202
    return {
 
203
        'verbose_name': force_unicode(opts.verbose_name),
 
204
        'verbose_name_plural': force_unicode(opts.verbose_name_plural)
 
205
    }
 
206
 
 
207
def model_ngettext(obj, n=None):
 
208
    """
 
209
    Return the appropriate `verbose_name` or `verbose_name_plural` value for
 
210
    `obj` depending on the count `n`.
 
211
 
 
212
    `obj` may be a `Model` instance, `Model` subclass, or `QuerySet` instance.
 
213
    If `obj` is a `QuerySet` instance, `n` is optional and the length of the
 
214
    `QuerySet` is used.
 
215
 
 
216
    """
 
217
    if isinstance(obj, models.query.QuerySet):
 
218
        if n is None:
 
219
            n = obj.count()
 
220
        obj = obj.model
 
221
    d = model_format_dict(obj)
 
222
    singular, plural = d["verbose_name"], d["verbose_name_plural"]
 
223
    return ungettext(singular, plural, n or 0)