web/lib/django/contrib/admin/helpers.py
author ymh <ymh.work@gmail.com>
Tue, 25 May 2010 02:43:45 +0200
changeset 29 cc9b7e14412b
parent 0 0d40e90630ef
permissions -rw-r--r--
update django and lucene
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
from django import forms
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
from django.conf import settings
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
     3
from django.contrib.admin.util import flatten_fieldsets, lookup_field
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
     4
from django.contrib.admin.util import display_for_field, label_for_field
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
     5
from django.contrib.contenttypes.models import ContentType
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
     6
from django.core.exceptions import ObjectDoesNotExist
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
     7
from django.db.models.fields import FieldDoesNotExist
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
     8
from django.db.models.fields.related import ManyToManyRel
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
     9
from django.forms.util import flatatt
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    10
from django.template.defaultfilters import capfirst
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    11
from django.utils.encoding import force_unicode, smart_unicode
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    12
from django.utils.html import escape, conditional_escape
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
from django.utils.safestring import mark_safe
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
from django.utils.translation import ugettext_lazy as _
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    16
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
ACTION_CHECKBOX_NAME = '_selected_action'
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
class ActionForm(forms.Form):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
    action = forms.ChoiceField(label=_('Action:'))
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    21
    select_across = forms.BooleanField(label='', required=False, initial=0,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    22
        widget=forms.HiddenInput({'class': 'select-across'}))
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
checkbox = forms.CheckboxInput({'class': 'action-select'}, lambda value: False)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
class AdminForm(object):
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    27
    def __init__(self, form, fieldsets, prepopulated_fields, readonly_fields=None, model_admin=None):
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
        self.form, self.fieldsets = form, normalize_fieldsets(fieldsets)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
        self.prepopulated_fields = [{
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
            'field': form[field_name],
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
            'dependencies': [form[f] for f in dependencies]
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
        } for field_name, dependencies in prepopulated_fields.items()]
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    33
        self.model_admin = model_admin
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    34
        if readonly_fields is None:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    35
            readonly_fields = ()
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    36
        self.readonly_fields = readonly_fields
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
    def __iter__(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
        for name, options in self.fieldsets:
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    40
            yield Fieldset(self.form, name,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    41
                readonly_fields=self.readonly_fields,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    42
                model_admin=self.model_admin,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    43
                **options
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    44
            )
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
    def first_field(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
        try:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
            fieldset_name, fieldset_options = self.fieldsets[0]
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
            field_name = fieldset_options['fields'][0]
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
            if not isinstance(field_name, basestring):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
                field_name = field_name[0]
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
            return self.form[field_name]
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
        except (KeyError, IndexError):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
            pass
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
        try:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
            return iter(self.form).next()
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
        except StopIteration:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
            return None
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
    def _media(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
        media = self.form.media
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
        for fs in self:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
            media = media + fs.media
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
        return media
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
    media = property(_media)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
class Fieldset(object):
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    68
    def __init__(self, form, name=None, readonly_fields=(), fields=(), classes=(),
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    69
      description=None, model_admin=None):
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
        self.form = form
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
        self.name, self.fields = name, fields
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
        self.classes = u' '.join(classes)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
        self.description = description
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    74
        self.model_admin = model_admin
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    75
        self.readonly_fields = readonly_fields
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
    def _media(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
        if 'collapse' in self.classes:
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    79
            js = ['js/jquery.min.js', 'js/jquery.init.js', 'js/collapse.min.js']
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    80
            return forms.Media(js=['%s%s' % (settings.ADMIN_MEDIA_PREFIX, url) for url in js])
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
        return forms.Media()
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
    media = property(_media)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
    def __iter__(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
        for field in self.fields:
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    86
            yield Fieldline(self.form, field, self.readonly_fields, model_admin=self.model_admin)
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
class Fieldline(object):
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    89
    def __init__(self, form, field, readonly_fields=None, model_admin=None):
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
        self.form = form # A django.forms.Form instance
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    91
        if not hasattr(field, "__iter__"):
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
            self.fields = [field]
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
        else:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
            self.fields = field
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    95
        self.model_admin = model_admin
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    96
        if readonly_fields is None:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    97
            readonly_fields = ()
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
    98
        self.readonly_fields = readonly_fields
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
    def __iter__(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
        for i, field in enumerate(self.fields):
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   102
            if field in self.readonly_fields:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   103
                yield AdminReadonlyField(self.form, field, is_first=(i == 0),
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   104
                    model_admin=self.model_admin)
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   105
            else:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   106
                yield AdminField(self.form, field, is_first=(i == 0))
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
    def errors(self):
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   109
        return mark_safe(u'\n'.join([self.form[f].errors.as_ul() for f in self.fields if f not in self.readonly_fields]).strip('\n'))
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
class AdminField(object):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
    def __init__(self, form, field, is_first):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
        self.field = form[field] # A django.forms.BoundField instance
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
        self.is_first = is_first # Whether this field is first on the line
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
        self.is_checkbox = isinstance(self.field.field.widget, forms.CheckboxInput)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
    def label_tag(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
        classes = []
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
        if self.is_checkbox:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
            classes.append(u'vCheckboxLabel')
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
            contents = force_unicode(escape(self.field.label))
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
        else:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
            contents = force_unicode(escape(self.field.label)) + u':'
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
        if self.field.field.required:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
            classes.append(u'required')
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
        if not self.is_first:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
            classes.append(u'inline')
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
        attrs = classes and {'class': u' '.join(classes)} or {}
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
        return self.field.label_tag(contents=contents, attrs=attrs)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   131
class AdminReadonlyField(object):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   132
    def __init__(self, form, field, is_first, model_admin=None):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   133
        label = label_for_field(field, form._meta.model, model_admin)
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   134
        # Make self.field look a little bit like a field. This means that
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   135
        # {{ field.name }} must be a useful class name to identify the field.
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   136
        # For convenience, store other field-related data here too.
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   137
        if callable(field):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   138
            class_name = field.__name__ != '<lambda>' and field.__name__ or ''
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   139
        else:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   140
            class_name = field
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   141
        self.field = {
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   142
            'name': class_name,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   143
            'label': label,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   144
            'field': field,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   145
        }
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   146
        self.form = form
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   147
        self.model_admin = model_admin
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   148
        self.is_first = is_first
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   149
        self.is_checkbox = False
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   150
        self.is_readonly = True
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   151
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   152
    def label_tag(self):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   153
        attrs = {}
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   154
        if not self.is_first:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   155
            attrs["class"] = "inline"
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   156
        label = self.field['label']
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   157
        contents = capfirst(force_unicode(escape(label))) + u":"
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   158
        return mark_safe('<label%(attrs)s>%(contents)s</label>' % {
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   159
            "attrs": flatatt(attrs),
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   160
            "contents": contents,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   161
        })
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   162
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   163
    def contents(self):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   164
        from django.contrib.admin.templatetags.admin_list import _boolean_icon
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   165
        from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   166
        field, obj, model_admin = self.field['field'], self.form.instance, self.model_admin
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   167
        try:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   168
            f, attr, value = lookup_field(field, obj, model_admin)
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   169
        except (AttributeError, ValueError, ObjectDoesNotExist):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   170
            result_repr = EMPTY_CHANGELIST_VALUE
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   171
        else:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   172
            if f is None:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   173
                boolean = getattr(attr, "boolean", False)
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   174
                if boolean:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   175
                    result_repr = _boolean_icon(value)
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   176
                else:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   177
                    result_repr = smart_unicode(value)
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   178
                    if getattr(attr, "allow_tags", False):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   179
                        result_repr = mark_safe(result_repr)
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   180
            else:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   181
                if value is None:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   182
                    result_repr = EMPTY_CHANGELIST_VALUE
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   183
                elif isinstance(f.rel, ManyToManyRel):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   184
                    result_repr = ", ".join(map(unicode, value.all()))
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   185
                else:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   186
                    result_repr = display_for_field(value, f)
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   187
        return conditional_escape(result_repr)
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   188
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   189
class InlineAdminFormSet(object):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   190
    """
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   191
    A wrapper around an inline formset for use in the admin system.
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   192
    """
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   193
    def __init__(self, inline, formset, fieldsets, readonly_fields=None, model_admin=None):
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   194
        self.opts = inline
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   195
        self.formset = formset
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   196
        self.fieldsets = fieldsets
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   197
        self.model_admin = model_admin
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   198
        if readonly_fields is None:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   199
            readonly_fields = ()
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   200
        self.readonly_fields = readonly_fields
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   201
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   202
    def __iter__(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   203
        for form, original in zip(self.formset.initial_forms, self.formset.get_queryset()):
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   204
            yield InlineAdminForm(self.formset, form, self.fieldsets,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   205
                self.opts.prepopulated_fields, original, self.readonly_fields,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   206
                model_admin=self.model_admin)
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   207
        for form in self.formset.extra_forms:
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   208
            yield InlineAdminForm(self.formset, form, self.fieldsets,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   209
                self.opts.prepopulated_fields, None, self.readonly_fields,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   210
                model_admin=self.model_admin)
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   211
        yield InlineAdminForm(self.formset, self.formset.empty_form,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   212
            self.fieldsets, self.opts.prepopulated_fields, None,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   213
            self.readonly_fields, model_admin=self.model_admin)
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   214
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   215
    def fields(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   216
        fk = getattr(self.formset, "fk", None)
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   217
        for i, field in enumerate(flatten_fieldsets(self.fieldsets)):
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   218
            if fk and fk.name == field:
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   219
                continue
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   220
            if field in self.readonly_fields:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   221
                yield {
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   222
                    'label': label_for_field(field, self.opts.model, self.model_admin),
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   223
                    'widget': {
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   224
                        'is_hidden': False
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   225
                    },
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   226
                    'required': False
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   227
                }
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   228
            else:
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   229
                yield self.formset.form.base_fields[field]
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   230
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   231
    def _media(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   232
        media = self.opts.media + self.formset.media
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   233
        for fs in self:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   234
            media = media + fs.media
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   235
        return media
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   236
    media = property(_media)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   237
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   238
class InlineAdminForm(AdminForm):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   239
    """
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   240
    A wrapper around an inline form for use in the admin system.
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   241
    """
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   242
    def __init__(self, formset, form, fieldsets, prepopulated_fields, original,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   243
      readonly_fields=None, model_admin=None):
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   244
        self.formset = formset
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   245
        self.model_admin = model_admin
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   246
        self.original = original
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   247
        if original is not None:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   248
            self.original_content_type_id = ContentType.objects.get_for_model(original).pk
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   249
        self.show_url = original and hasattr(original, 'get_absolute_url')
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   250
        super(InlineAdminForm, self).__init__(form, fieldsets, prepopulated_fields,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   251
            readonly_fields, model_admin)
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   252
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   253
    def __iter__(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   254
        for name, options in self.fieldsets:
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   255
            yield InlineFieldset(self.formset, self.form, name,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   256
                self.readonly_fields, model_admin=self.model_admin, **options)
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   257
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   258
    def has_auto_field(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   259
        if self.form._meta.model._meta.has_auto_field:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   260
            return True
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   261
        # Also search any parents for an auto field.
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   262
        for parent in self.form._meta.model._meta.get_parent_list():
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   263
            if parent._meta.has_auto_field:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   264
                return True
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   265
        return False
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   266
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   267
    def field_count(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   268
        # tabular.html uses this function for colspan value.
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   269
        num_of_fields = 0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   270
        if self.has_auto_field():
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   271
            num_of_fields += 1
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   272
        num_of_fields += len(self.fieldsets[0][1]["fields"])
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   273
        if self.formset.can_order:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   274
            num_of_fields += 1
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   275
        if self.formset.can_delete:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   276
            num_of_fields += 1
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   277
        return num_of_fields
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   278
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   279
    def pk_field(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   280
        return AdminField(self.form, self.formset._pk_field.name, False)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   281
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   282
    def fk_field(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   283
        fk = getattr(self.formset, "fk", None)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   284
        if fk:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   285
            return AdminField(self.form, fk.name, False)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   286
        else:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   287
            return ""
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   288
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   289
    def deletion_field(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   290
        from django.forms.formsets import DELETION_FIELD_NAME
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   291
        return AdminField(self.form, DELETION_FIELD_NAME, False)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   292
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   293
    def ordering_field(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   294
        from django.forms.formsets import ORDERING_FIELD_NAME
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   295
        return AdminField(self.form, ORDERING_FIELD_NAME, False)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   296
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   297
class InlineFieldset(Fieldset):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   298
    def __init__(self, formset, *args, **kwargs):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   299
        self.formset = formset
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   300
        super(InlineFieldset, self).__init__(*args, **kwargs)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   301
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   302
    def __iter__(self):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   303
        fk = getattr(self.formset, "fk", None)
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   304
        for field in self.fields:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   305
            if fk and fk.name == field:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   306
                continue
29
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   307
            yield Fieldline(self.form, field, self.readonly_fields,
cc9b7e14412b update django and lucene
ymh <ymh.work@gmail.com>
parents: 0
diff changeset
   308
                model_admin=self.model_admin)
0
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   309
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   310
class AdminErrorList(forms.util.ErrorList):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   311
    """
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   312
    Stores all errors for the form/formsets in an add/change stage view.
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   313
    """
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   314
    def __init__(self, form, inline_formsets):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   315
        if form.is_bound:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   316
            self.extend(form.errors.values())
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   317
            for inline_formset in inline_formsets:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   318
                self.extend(inline_formset.non_form_errors())
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   319
                for errors_in_inline_form in inline_formset.errors:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   320
                    self.extend(errors_in_inline_form.values())
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   321
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   322
def normalize_fieldsets(fieldsets):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   323
    """
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   324
    Make sure the keys in fieldset dictionaries are strings. Returns the
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   325
    normalized data.
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   326
    """
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   327
    result = []
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   328
    for name, options in fieldsets:
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   329
        result.append((name, normalize_dictionary(options)))
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   330
    return result
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   331
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   332
def normalize_dictionary(data_dict):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   333
    """
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   334
    Converts all the keys in "data_dict" to strings. The keys must be
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   335
    convertible using str().
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   336
    """
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   337
    for key, value in data_dict.items():
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   338
        if not isinstance(key, str):
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   339
            del data_dict[key]
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   340
            data_dict[str(key)] = value
0d40e90630ef Blinkster creation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   341
    return data_dict