Django

Code

root/django/trunk/django/contrib/admin/util.py

Revision 8616, 7.0 kB (checked in by gwilson, 3 months ago)

Removed oldforms, validators, and related code:

  • Removed Manipulator, AutomaticManipulator, and related classes.
  • Removed oldforms specific bits from model fields:
    • Removed validator_list and core arguments from constructors.
    • Removed the methods:
      • get_manipulator_field_names
      • get_manipulator_field_objs
      • get_manipulator_fields
      • get_manipulator_new_data
      • prepare_field_objs_and_params
      • get_follow
    • Renamed flatten_data method to value_to_string for better alignment with its use by the serialization framework, which was the only remaining code using flatten_data.
  • Removed oldforms methods from django.db.models.Options class: get_followed_related_objects, get_data_holders, get_follow, and has_field_type.
  • Removed oldforms-admin specific options from django.db.models.fields.related classes: num_in_admin, min_num_in_admin, max_num_in_admin, num_extra_on_change, and edit_inline.
  • Serialization framework
    • Serializer.get_string_value now calls the model fields' renamed value_to_string methods.
    • Removed a special-casing of models.DateTimeField in core.serializers.base.Serializer.get_string_value that's handled by django.db.models.fields.DateTimeField.value_to_string.
  • Removed django.core.validators:
    • Moved ValidationError exception to django.core.exceptions.
    • For the couple places that were using validators, brought over the necessary code to maintain the same functionality.
  • Introduced a SlugField? form field for validation and to compliment the SlugField? model field (refs #8040).
  • Removed an oldforms-style model creation hack (refs #2160).
Line 
1 from django.core.exceptions import ObjectDoesNotExist
2 from django.db import models
3 from django.utils.html import escape
4 from django.utils.safestring import mark_safe
5 from django.utils.text import capfirst
6 from django.utils.encoding import force_unicode
7 from django.utils.translation import ugettext as _
8
9
10 def quote(s):
11     """
12     Ensure that primary key values do not confuse the admin URLs by escaping
13     any '/', '_' and ':' characters. Similar to urllib.quote, except that the
14     quoting is slightly different so that it doesn't get automatically
15     unquoted by the Web browser.
16     """
17     if not isinstance(s, basestring):
18         return s
19     res = list(s)
20     for i in range(len(res)):
21         c = res[i]
22         if c in """:/_#?;@&=+$,"<>%\\""":
23             res[i] = '_%02X' % ord(c)
24     return ''.join(res)
25
26 def unquote(s):
27     """
28     Undo the effects of quote(). Based heavily on urllib.unquote().
29     """
30     mychr = chr
31     myatoi = int
32     list = s.split('_')
33     res = [list[0]]
34     myappend = res.append
35     del list[0]
36     for item in list:
37         if item[1:2]:
38             try:
39                 myappend(mychr(myatoi(item[:2], 16)) + item[2:])
40             except ValueError:
41                 myappend('_' + item)
42         else:
43             myappend('_' + item)
44     return "".join(res)
45
46 def flatten_fieldsets(fieldsets):
47     """Returns a list of field names from an admin fieldsets structure."""
48     field_names = []
49     for name, opts in fieldsets:
50         for field in opts['fields']:
51             # type checking feels dirty, but it seems like the best way here
52             if type(field) == tuple:
53                 field_names.extend(field)
54             else:
55                 field_names.append(field)
56     return field_names
57
58 def _nest_help(obj, depth, val):
59     current = obj
60     for i in range(depth):
61         current = current[-1]
62     current.append(val)
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."
66     nh = _nest_help # Bind to local variable for performance
67     if current_depth > 16:
68         return # Avoid recursing too deep.
69     opts_seen = []
70     for related in opts.get_all_related_objects():
71         has_admin = related.model in admin_site._registry
72         if related.opts in opts_seen:
73             continue
74         opts_seen.append(related.opts)
75         rel_opts_name = related.get_accessor_name()
76         if isinstance(related.field.rel, models.OneToOneRel):
77             try:
78                 sub_obj = getattr(obj, rel_opts_name)
79             except ObjectDoesNotExist:
80                 pass
81             else:
82                 if has_admin:
83                     p = '%s.%s' % (related.opts.app_label, related.opts.get_delete_permission())
84                     if not user.has_perm(p):
85                         perms_needed.add(related.opts.verbose_name)
86                         # We don't care about populating deleted_objects now.
87                         continue
88                 if not has_admin:
89                     # Don't display link to edit, because it either has no
90                     # admin or is edited inline.
91                     nh(deleted_objects, current_depth, [u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), sub_obj), []])
92                 else:
93                     # 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)), []])
99                 get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2, admin_site)
100         else:
101             has_related_objs = False
102             for sub_obj in getattr(obj, rel_opts_name).all():
103                 has_related_objs = True
104                 if not has_admin:
105                     # Don't display link to edit, because it either has no
106                     # admin or is edited inline.
107                     nh(deleted_objects, current_depth, [u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), sub_obj), []])
108                 else:
109                     # 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))), []])
112                 get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2, admin_site)
113             # If there were related objects, and the user doesn't have
114             # permission to delete them, add the missing perm to perms_needed.
115             if has_admin and has_related_objs:
116                 p = '%s.%s' % (related.opts.app_label, related.opts.get_delete_permission())
117                 if not user.has_perm(p):
118                     perms_needed.add(related.opts.verbose_name)
119     for related in opts.get_all_related_many_to_many_objects():
120         has_admin = related.model in admin_site._registry
121         if related.opts in opts_seen:
122             continue
123         opts_seen.append(related.opts)
124         rel_opts_name = related.get_accessor_name()
125         has_related_objs = False
126
127         # related.get_accessor_name() could return None for symmetrical relationships
128         if rel_opts_name:
129             rel_objs = getattr(obj, rel_opts_name, None)
130             if rel_objs:
131                 has_related_objs = True
132
133         if has_related_objs:
134             for sub_obj in rel_objs.all():
135                 if not has_admin:
136                     # Don't display link to edit, because it either has no
137                     # admin or is edited inline.
138                     nh(deleted_objects, current_depth, [_('One or more %(fieldname)s in %(name)s: %(obj)s') % \
139                         {'fieldname': force_unicode(related.field.verbose_name), 'name': force_unicode(related.opts.verbose_name), 'obj': escape(sub_obj)}, []])
140                 else:
141                     # Display a link to the admin page.
142                     nh(deleted_objects, current_depth, [
143                         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)))), []])
146         # If there were related objects, and the user doesn't have
147         # permission to change them, add the missing perm to perms_needed.
148         if has_admin and has_related_objs:
149             p = u'%s.%s' % (related.opts.app_label, related.opts.get_change_permission())
150             if not user.has_perm(p):
151                 perms_needed.add(related.opts.verbose_name)
Note: See TracBrowser for help on using the browser.