2008-07-19 07:54:34 +08:00
from django . core . exceptions import ObjectDoesNotExist
from django . db import models
from django . utils . html import escape
from django . utils . safestring import mark_safe
from django . utils . text import capfirst
from django . utils . encoding import force_unicode
from django . utils . translation import ugettext as _
def quote ( s ) :
"""
Ensure that primary key values do not confuse the admin URLs by escaping
any ' / ' , ' _ ' and ' : ' characters . Similar to urllib . quote , except that the
quoting is slightly different so that it doesn ' t get automatically
unquoted by the Web browser .
"""
if not isinstance ( s , basestring ) :
return s
res = list ( s )
for i in range ( len ( res ) ) :
c = res [ i ]
if c in """ :/_#?;@&=+$, " <> % \\ """ :
res [ i ] = ' _ %02X ' % ord ( c )
return ' ' . join ( res )
def unquote ( s ) :
"""
Undo the effects of quote ( ) . Based heavily on urllib . unquote ( ) .
"""
mychr = chr
myatoi = int
list = s . split ( ' _ ' )
res = [ list [ 0 ] ]
myappend = res . append
del list [ 0 ]
for item in list :
if item [ 1 : 2 ] :
try :
myappend ( mychr ( myatoi ( item [ : 2 ] , 16 ) ) + item [ 2 : ] )
except ValueError :
myappend ( ' _ ' + item )
else :
myappend ( ' _ ' + item )
return " " . join ( res )
2008-08-18 23:49:58 +08:00
def flatten_fieldsets ( fieldsets ) :
""" Returns a list of field names from an admin fieldsets structure. """
field_names = [ ]
for name , opts in fieldsets :
for field in opts [ ' fields ' ] :
# type checking feels dirty, but it seems like the best way here
if type ( field ) == tuple :
field_names . extend ( field )
else :
field_names . append ( field )
return field_names
2008-07-19 07:54:34 +08:00
def _nest_help ( obj , depth , val ) :
current = obj
for i in range ( depth ) :
current = current [ - 1 ]
current . append ( val )
def get_deleted_objects ( deleted_objects , perms_needed , user , obj , opts , current_depth , admin_site ) :
" Helper function that recursively populates deleted_objects. "
nh = _nest_help # Bind to local variable for performance
if current_depth > 16 :
return # Avoid recursing too deep.
opts_seen = [ ]
for related in opts . get_all_related_objects ( ) :
has_admin = related . model in admin_site . _registry
if related . opts in opts_seen :
continue
opts_seen . append ( related . opts )
rel_opts_name = related . get_accessor_name ( )
if isinstance ( related . field . rel , models . OneToOneRel ) :
try :
sub_obj = getattr ( obj , rel_opts_name )
except ObjectDoesNotExist :
pass
else :
if has_admin :
p = ' %s . %s ' % ( related . opts . app_label , related . opts . get_delete_permission ( ) )
if not user . has_perm ( p ) :
perms_needed . add ( related . opts . verbose_name )
# We don't care about populating deleted_objects now.
continue
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).
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8616 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-08-27 15:19:44 +08:00
if not has_admin :
2008-07-19 07:54:34 +08:00
# Don't display link to edit, because it either has no
# admin or is edited inline.
2008-08-26 15:36:39 +08:00
nh ( deleted_objects , current_depth , [ u ' %s : %s ' % ( force_unicode ( capfirst ( related . opts . verbose_name ) ) , sub_obj ) , [ ] ] )
2008-07-19 07:54:34 +08:00
else :
# Display a link to the admin page.
nh ( deleted_objects , current_depth , [ mark_safe ( u ' %s : <a href= " ../../../../ %s / %s / %s / " > %s </a> ' %
( escape ( force_unicode ( capfirst ( related . opts . verbose_name ) ) ) ,
related . opts . app_label ,
related . opts . object_name . lower ( ) ,
sub_obj . _get_pk_val ( ) , sub_obj ) ) , [ ] ] )
get_deleted_objects ( deleted_objects , perms_needed , user , sub_obj , related . opts , current_depth + 2 , admin_site )
else :
has_related_objs = False
for sub_obj in getattr ( obj , rel_opts_name ) . all ( ) :
has_related_objs = True
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).
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8616 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-08-27 15:19:44 +08:00
if not has_admin :
2008-07-19 07:54:34 +08:00
# Don't display link to edit, because it either has no
# admin or is edited inline.
2008-12-16 23:04:47 +08:00
nh ( deleted_objects , current_depth , [ u ' %s : %s ' % ( capfirst ( related . opts . verbose_name ) , force_unicode ( sub_obj ) ) , [ ] ] )
2008-07-19 07:54:34 +08:00
else :
# Display a link to the admin page.
nh ( deleted_objects , current_depth , [ mark_safe ( u ' %s : <a href= " ../../../../ %s / %s / %s / " > %s </a> ' % \
( 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 ) ) ) , [ ] ] )
get_deleted_objects ( deleted_objects , perms_needed , user , sub_obj , related . opts , current_depth + 2 , admin_site )
# If there were related objects, and the user doesn't have
# permission to delete them, add the missing perm to perms_needed.
if has_admin and has_related_objs :
p = ' %s . %s ' % ( related . opts . app_label , related . opts . get_delete_permission ( ) )
if not user . has_perm ( p ) :
perms_needed . add ( related . opts . verbose_name )
for related in opts . get_all_related_many_to_many_objects ( ) :
has_admin = related . model in admin_site . _registry
if related . opts in opts_seen :
continue
opts_seen . append ( related . opts )
rel_opts_name = related . get_accessor_name ( )
has_related_objs = False
# related.get_accessor_name() could return None for symmetrical relationships
if rel_opts_name :
rel_objs = getattr ( obj , rel_opts_name , None )
if rel_objs :
has_related_objs = True
if has_related_objs :
for sub_obj in rel_objs . all ( ) :
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).
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8616 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-08-27 15:19:44 +08:00
if not has_admin :
2008-07-19 07:54:34 +08:00
# Don't display link to edit, because it either has no
# admin or is edited inline.
nh ( deleted_objects , current_depth , [ _ ( ' One or more %(fieldname)s in %(name)s : %(obj)s ' ) % \
{ ' fieldname ' : force_unicode ( related . field . verbose_name ) , ' name ' : force_unicode ( related . opts . verbose_name ) , ' obj ' : escape ( sub_obj ) } , [ ] ] )
else :
# Display a link to the admin page.
nh ( deleted_objects , current_depth , [
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 ) ) } ) + \
( u ' <a href= " ../../../../ %s / %s / %s / " > %s </a> ' % \
( related . opts . app_label , related . opts . module_name , sub_obj . _get_pk_val ( ) , escape ( sub_obj ) ) ) ) , [ ] ] )
# If there were related objects, and the user doesn't have
# permission to change them, add the missing perm to perms_needed.
if has_admin and has_related_objs :
p = u ' %s . %s ' % ( related . opts . app_label , related . opts . get_change_permission ( ) )
if not user . has_perm ( p ) :
perms_needed . add ( related . opts . verbose_name )