| 1 |
import copy |
|---|
| 2 |
import datetime |
|---|
| 3 |
import os |
|---|
| 4 |
import time |
|---|
| 5 |
try: |
|---|
| 6 |
import decimal |
|---|
| 7 |
except ImportError: |
|---|
| 8 |
from django.utils import _decimal as decimal # for Python 2.3 |
|---|
| 9 |
|
|---|
| 10 |
from django.db import connection, get_creation_module |
|---|
| 11 |
from django.db.models import signals |
|---|
| 12 |
from django.db.models.query_utils import QueryWrapper |
|---|
| 13 |
from django.dispatch import dispatcher |
|---|
| 14 |
from django.conf import settings |
|---|
| 15 |
from django.core import validators |
|---|
| 16 |
from django import oldforms |
|---|
| 17 |
from django import newforms as forms |
|---|
| 18 |
from django.core.exceptions import ObjectDoesNotExist |
|---|
| 19 |
from django.utils.datastructures import DictWrapper |
|---|
| 20 |
from django.utils.functional import curry |
|---|
| 21 |
from django.utils.itercompat import tee |
|---|
| 22 |
from django.utils.text import capfirst |
|---|
| 23 |
from django.utils.translation import ugettext_lazy, ugettext as _ |
|---|
| 24 |
from django.utils.encoding import smart_unicode, force_unicode, smart_str |
|---|
| 25 |
from django.utils.maxlength import LegacyMaxlength |
|---|
| 26 |
|
|---|
| 27 |
class NOT_PROVIDED: |
|---|
| 28 |
pass |
|---|
| 29 |
|
|---|
| 30 |
# Values for filter_interface. |
|---|
| 31 |
HORIZONTAL, VERTICAL = 1, 2 |
|---|
| 32 |
|
|---|
| 33 |
# The values to use for "blank" in SelectFields. Will be appended to the start of most "choices" lists. |
|---|
| 34 |
BLANK_CHOICE_DASH = [("", "---------")] |
|---|
| 35 |
BLANK_CHOICE_NONE = [("", "None")] |
|---|
| 36 |
|
|---|
| 37 |
# returns the <ul> class for a given radio_admin value |
|---|
| 38 |
get_ul_class = lambda x: 'radiolist%s' % ((x == HORIZONTAL) and ' inline' or '') |
|---|
| 39 |
|
|---|
| 40 |
class FieldDoesNotExist(Exception): |
|---|
| 41 |
pass |
|---|
| 42 |
|
|---|
| 43 |
def manipulator_validator_unique(f, opts, self, field_data, all_data): |
|---|
| 44 |
"Validates that the value is unique for this field." |
|---|
| 45 |
lookup_type = f.get_validator_unique_lookup_type() |
|---|
| 46 |
try: |
|---|
| 47 |
old_obj = self.manager.get(**{lookup_type: field_data}) |
|---|
| 48 |
except ObjectDoesNotExist: |
|---|
| 49 |
return |
|---|
| 50 |
if getattr(self, 'original_object', None) and self.original_object._get_pk_val() == old_obj._get_pk_val(): |
|---|
| 51 |
return |
|---|
| 52 |
raise validators.ValidationError, _("%(optname)s with this %(fieldname)s already exists.") % {'optname': capfirst(opts.verbose_name), 'fieldname': f.verbose_name} |
|---|
| 53 |
|
|---|
| 54 |
# A guide to Field parameters: |
|---|
| 55 |
# |
|---|
| 56 |
# * name: The name of the field specifed in the model. |
|---|
| 57 |
# * attname: The attribute to use on the model object. This is the same as |
|---|
| 58 |
# "name", except in the case of ForeignKeys, where "_id" is |
|---|
| 59 |
# appended. |
|---|
| 60 |
# * db_column: The db_column specified in the model (or None). |
|---|
| 61 |
# * column: The database column for this field. This is the same as |
|---|
| 62 |
# "attname", except if db_column is specified. |
|---|
| 63 |
# |
|---|
| 64 |
# Code that introspects values, or does other dynamic things, should use |
|---|
| 65 |
# attname. For example, this gets the primary key value of object "obj": |
|---|
| 66 |
# |
|---|
| 67 |
# getattr(obj, opts.pk.attname) |
|---|
| 68 |
|
|---|
| 69 |
class Field(object): |
|---|
| 70 |
# Provide backwards compatibility for the maxlength attribute and |
|---|
| 71 |
# argument for this class and all subclasses. |
|---|
| 72 |
__metaclass__ = LegacyMaxlength |
|---|
| 73 |
|
|---|
| 74 |
# Designates whether empty strings fundamentally are allowed at the |
|---|
| 75 |
# database level. |
|---|
| 76 |
empty_strings_allowed = True |
|---|
| 77 |
|
|---|
| 78 |
# These track each time a Field instance is created. Used to retain order. |
|---|
| 79 |
# The auto_creation_counter is used for fields that Django implicitly |
|---|
| 80 |
# creates, creation_counter is used for all user-specified fields. |
|---|
| 81 |
creation_counter = 0 |
|---|
| 82 |
auto_creation_counter = -1 |
|---|
| 83 |
|
|---|
| 84 |
def __init__(self, verbose_name=None, name=None, primary_key=False, |
|---|
| 85 |
max_length=None, unique=False, blank=False, null=False, |
|---|
| 86 |
db_index=False, core=False, rel=None, default=NOT_PROVIDED, |
|---|
| 87 |
editable=True, serialize=True, prepopulate_from=None, |
|---|
| 88 |
unique_for_date=None, unique_for_month=None, unique_for_year=None, |
|---|
| 89 |
validator_list=None, choices=None, radio_admin=None, help_text='', |
|---|
| 90 |
db_column=None, db_tablespace=None, auto_created=False): |
|---|
| 91 |
self.name = name |
|---|
| 92 |
self.verbose_name = verbose_name |
|---|
| 93 |
self.primary_key = primary_key |
|---|
| 94 |
self.max_length, self._unique = max_length, unique |
|---|
| 95 |
self.blank, self.null = blank, null |
|---|
| 96 |
# Oracle treats the empty string ('') as null, so coerce the null |
|---|
| 97 |
# option whenever '' is a possible value. |
|---|
| 98 |
if self.empty_strings_allowed and connection.features.interprets_empty_strings_as_nulls: |
|---|
| 99 |
self.null = True |
|---|
| 100 |
self.core, self.rel, self.default = core, rel, default |
|---|
| 101 |
self.editable = editable |
|---|
| 102 |
self.serialize = serialize |
|---|
| 103 |
self.validator_list = validator_list or [] |
|---|
| 104 |
self.prepopulate_from = prepopulate_from |
|---|
| 105 |
self.unique_for_date, self.unique_for_month = unique_for_date, unique_for_month |
|---|
| 106 |
self.unique_for_year = unique_for_year |
|---|
| 107 |
self._choices = choices or [] |
|---|
| 108 |
self.radio_admin = radio_admin |
|---|
| 109 |
self.help_text = help_text |
|---|
| 110 |
self.db_column = db_column |
|---|
| 111 |
self.db_tablespace = db_tablespace or settings.DEFAULT_INDEX_TABLESPACE |
|---|
| 112 |
|
|---|
| 113 |
# Set db_index to True if the field has a relationship and doesn't explicitly set db_index. |
|---|
| 114 |
self.db_index = db_index |
|---|
| 115 |
|
|---|
| 116 |
# Adjust the appropriate creation counter, and save our local copy. |
|---|
| 117 |
if auto_created: |
|---|
| 118 |
self.creation_counter = Field.auto_creation_counter |
|---|
| 119 |
Field.auto_creation_counter -= 1 |
|---|
| 120 |
else: |
|---|
| 121 |
self.creation_counter = Field.creation_counter |
|---|
| 122 |
Field.creation_counter += 1 |
|---|
| 123 |
|
|---|
| 124 |
def __cmp__(self, other): |
|---|
| 125 |
# This is needed because bisect does not take a comparison function. |
|---|
| 126 |
return cmp(self.creation_counter, other.creation_counter) |
|---|
| 127 |
|
|---|
| 128 |
def __deepcopy__(self, memodict): |
|---|
| 129 |
# We don't have to deepcopy very much here, since most things are not |
|---|
| 130 |
# intended to be altered after initial creation. |
|---|
| 131 |
obj = copy.copy(self) |
|---|
| 132 |
if self.rel: |
|---|
| 133 |
obj.rel = copy.copy(self.rel) |
|---|
| 134 |
memodict[id(self)] = obj |
|---|
| 135 |
return obj |
|---|
| 136 |
|
|---|
| 137 |
def to_python(self, value): |
|---|
| 138 |
""" |
|---|
| 139 |
Converts the input value into the expected Python data type, raising |
|---|
| 140 |
validators.ValidationError if the data can't be converted. Returns the |
|---|
| 141 |
converted value. Subclasses should override this. |
|---|
| 142 |
""" |
|---|
| 143 |
return value |
|---|
| 144 |
|
|---|
| 145 |
def db_type(self): |
|---|
| 146 |
""" |
|---|
| 147 |
Returns the database column data type for this field, taking into |
|---|
| 148 |
account the DATABASE_ENGINE setting. |
|---|
| 149 |
""" |
|---|
| 150 |
# The default implementation of this method looks at the |
|---|
| 151 |
# backend-specific DATA_TYPES dictionary, looking up the field by its |
|---|
| 152 |
# "internal type". |
|---|
| 153 |
# |
|---|
| 154 |
# A Field class can implement the get_internal_type() method to specify |
|---|
| 155 |
# which *preexisting* Django Field class it's most similar to -- i.e., |
|---|
| 156 |
# an XMLField is represented by a TEXT column type, which is the same |
|---|
| 157 |
# as the TextField Django field type, which means XMLField's |
|---|
| 158 |
# get_internal_type() returns 'TextField'. |
|---|
| 159 |
# |
|---|
| 160 |
# But the limitation of the get_internal_type() / DATA_TYPES approach |
|---|
| 161 |
# is that it cannot handle database column types that aren't already |
|---|
| 162 |
# mapped to one of the built-in Django field types. In this case, you |
|---|
| 163 |
# can implement db_type() instead of get_internal_type() to specify |
|---|
| 164 |
# exactly which wacky database column type you want to use. |
|---|
| 165 |
data = DictWrapper(self.__dict__, connection.ops.quote_name, "qn_") |
|---|
| 166 |
try: |
|---|
| 167 |
return get_creation_module().DATA_TYPES[self.get_internal_type()] % data |
|---|
| 168 |
except KeyError: |
|---|
| 169 |
return None |
|---|
| 170 |
|
|---|
| 171 |
def unique(self): |
|---|
| 172 |
return self._unique or self.primary_key |
|---|
| 173 |
unique = property(unique) |
|---|
| 174 |
|
|---|
| 175 |
def validate_full(self, field_data, all_data): |
|---|
| 176 |
""" |
|---|
| 177 |
Returns a list of errors for this field. This is the main interface, |
|---|
| 178 |
as it encapsulates some basic validation logic used by all fields. |
|---|
| 179 |
Subclasses should implement validate(), not validate_full(). |
|---|
| 180 |
""" |
|---|
| 181 |
if not self.blank and not field_data: |
|---|
| 182 |
return [_('This field is required.')] |
|---|
| 183 |
try: |
|---|
| 184 |
self.validate(field_data, all_data) |
|---|
| 185 |
except validators.ValidationError, e: |
|---|
| 186 |
return e.messages |
|---|
| 187 |
return [] |
|---|
| 188 |
|
|---|
| 189 |
def validate(self, field_data, all_data): |
|---|
| 190 |
""" |
|---|
| 191 |
Raises validators.ValidationError if field_data has any errors. |
|---|
| 192 |
Subclasses should override this to specify field-specific validation |
|---|
| 193 |
logic. This method should assume field_data has already been converted |
|---|
| 194 |
into the appropriate data type by Field.to_python(). |
|---|
| 195 |
""" |
|---|
| 196 |
pass |
|---|
| 197 |
|
|---|
| 198 |
def set_attributes_from_name(self, name): |
|---|
| 199 |
self.name = name |
|---|
| 200 |
self.attname, self.column = self.get_attname_column() |
|---|
| 201 |
self.verbose_name = self.verbose_name or (name and name.replace('_', ' ')) |
|---|
| 202 |
|
|---|
| 203 |
def contribute_to_class(self, cls, name): |
|---|
| 204 |
self.set_attributes_from_name(name) |
|---|
| 205 |
cls._meta.add_field(self) |
|---|
| 206 |
if self.choices: |
|---|
| 207 |
setattr(cls, 'get_%s_display' % self.name, curry(cls._get_FIELD_display, field=self)) |
|---|
| 208 |
|
|---|
| 209 |
def get_attname(self): |
|---|
| 210 |
return self.name |
|---|
| 211 |
|
|---|
| 212 |
def get_attname_column(self): |
|---|
| 213 |
attname = self.get_attname() |
|---|
| 214 |
column = self.db_column or attname |
|---|
| 215 |
return attname, column |
|---|
| 216 |
|
|---|
| 217 |
def get_cache_name(self): |
|---|
| 218 |
return '_%s_cache' % self.name |
|---|
| 219 |
|
|---|
| 220 |
def get_internal_type(self): |
|---|
| 221 |
return self.__class__.__name__ |
|---|
| 222 |
|
|---|
| 223 |
def pre_save(self, model_instance, add): |
|---|
| 224 |
"Returns field's value just before saving." |
|---|
| 225 |
return getattr(model_instance, self.attname) |
|---|
| 226 |
|
|---|
| 227 |
def get_db_prep_save(self, value): |
|---|
| 228 |
"Returns field's value prepared for saving into a database." |
|---|
| 229 |
return value |
|---|
| 230 |
|
|---|
| 231 |
def get_db_prep_lookup(self, lookup_type, value): |
|---|
| 232 |
"Returns field's value prepared for database lookup." |
|---|
| 233 |
if hasattr(value, 'as_sql'): |
|---|
| 234 |
sql, params = value.as_sql() |
|---|
| 235 |
return QueryWrapper(('(%s)' % sql), params) |
|---|
| 236 |
if lookup_type in ('exact', 'regex', 'iregex', 'gt', 'gte', 'lt', 'lte', 'month', 'day', 'search'): |
|---|
| 237 |
return [value] |
|---|
| 238 |
elif lookup_type in ('range', 'in'): |
|---|
| 239 |
return value |
|---|
| 240 |
elif lookup_type in ('contains', 'icontains'): |
|---|
| 241 |
return ["%%%s%%" % connection.ops.prep_for_like_query(value)] |
|---|
| 242 |
elif lookup_type == 'iexact': |
|---|
| 243 |
return [connection.ops.prep_for_like_query(value)] |
|---|
| 244 |
elif lookup_type in ('startswith', 'istartswith'): |
|---|
| 245 |
return ["%s%%" % connection.ops.prep_for_like_query(value)] |
|---|
| 246 |
elif lookup_type in ('endswith', 'iendswith'): |
|---|
| 247 |
return ["%%%s" % connection.ops.prep_for_like_query(value)] |
|---|
| 248 |
elif lookup_type == 'isnull': |
|---|
| 249 |
return [] |
|---|
| 250 |
elif lookup_type == 'year': |
|---|
| 251 |
try: |
|---|
| 252 |
value = int(value) |
|---|
| 253 |
except ValueError: |
|---|
| 254 |
raise ValueError("The __year lookup type requires an integer argument") |
|---|
| 255 |
if settings.DATABASE_ENGINE == 'sqlite3': |
|---|
| 256 |
first = '%s-01-01' |
|---|
| 257 |
second = '%s-12-31 23:59:59.999999' |
|---|
| 258 |
elif not connection.features.date_field_supports_time_value and self.get_internal_type() == 'DateField': |
|---|
| 259 |
first = '%s-01-01' |
|---|
| 260 |
second = '%s-12-31' |
|---|
| 261 |
elif not connection.features.supports_usecs: |
|---|
| 262 |
first = '%s-01-01 00:00:00' |
|---|
| 263 |
second = '%s-12-31 23:59:59.99' |
|---|
| 264 |
else: |
|---|
| 265 |
first = '%s-01-01 00:00:00' |
|---|
| 266 |
second = '%s-12-31 23:59:59.999999' |
|---|
| 267 |
return [first % value, second % value] |
|---|
| 268 |
raise TypeError("Field has invalid lookup: %s" % lookup_type) |
|---|
| 269 |
|
|---|
| 270 |
def has_default(self): |
|---|
| 271 |
"Returns a boolean of whether this field has a default value." |
|---|
| 272 |
return self.default is not NOT_PROVIDED |
|---|
| 273 |
|
|---|
| 274 |
def get_default(self): |
|---|
| 275 |
"Returns the default value for this field." |
|---|
| 276 |
if self.default is not NOT_PROVIDED: |
|---|
| 277 |
if callable(self.default): |
|---|
| 278 |
return self.default() |
|---|
| 279 |
return force_unicode(self.default, strings_only=True) |
|---|
| 280 |
if not self.empty_strings_allowed or (self.null and not connection.features.interprets_empty_strings_as_nulls): |
|---|
| 281 |
return None |
|---|
| 282 |
return "" |
|---|
| 283 |
|
|---|
| 284 |
def get_manipulator_field_names(self, name_prefix): |
|---|
| 285 |
""" |
|---|
| 286 |
Returns a list of field names that this object adds to the manipulator. |
|---|
| 287 |
""" |
|---|
| 288 |
return [name_prefix + self.name] |
|---|
| 289 |
|
|---|
| 290 |
def prepare_field_objs_and_params(self, manipulator, name_prefix): |
|---|
| 291 |
params = {'validator_list': self.validator_list[:]} |
|---|
| 292 |
if self.max_length and not self.choices: # Don't give SelectFields a max_length parameter. |
|---|
| 293 |
params['max_length'] = self.max_length |
|---|
| 294 |
|
|---|
| 295 |
if self.choices: |
|---|
| 296 |
if self.radio_admin: |
|---|
| 297 |
field_objs = [oldforms.RadioSelectField] |
|---|
| 298 |
params['ul_class'] = get_ul_class(self.radio_admin) |
|---|
| 299 |
else: |
|---|
| 300 |
field_objs = [oldforms.SelectField] |
|---|
| 301 |
|
|---|
| 302 |
params['choices'] = self.get_choices_default() |
|---|
| 303 |
else: |
|---|
| 304 |
field_objs = self.get_manipulator_field_objs() |
|---|
| 305 |
return (field_objs, params) |
|---|
| 306 |
|
|---|
| 307 |
def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True): |
|---|
| 308 |
""" |
|---|
| 309 |
Returns a list of oldforms.FormField instances for this field. It |
|---|
| 310 |
calculates the choices at runtime, not at compile time. |
|---|
| 311 |
|
|---|
| 312 |
name_prefix is a prefix to prepend to the "field_name" argument. |
|---|
| 313 |
rel is a boolean specifying whether this field is in a related context. |
|---|
| 314 |
""" |
|---|
| 315 |
field_objs, params = self.prepare_field_objs_and_params(manipulator, name_prefix) |
|---|
| 316 |
|
|---|
| 317 |
# Add the "unique" validator(s). |
|---|
| 318 |
for field_name_list in opts.unique_together: |
|---|
| 319 |
if field_name_list[0] == self.name: |
|---|
| 320 |
params['validator_list'].append(getattr(manipulator, 'isUnique%s' % '_'.join(field_name_list))) |
|---|
| 321 |
|
|---|
| 322 |
# Add the "unique for..." validator(s). |
|---|
| 323 |
if self.unique_for_date: |
|---|
| 324 |
params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_date))) |
|---|
| 325 |
if self.unique_for_month: |
|---|
| 326 |
params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_month))) |
|---|
| 327 |
if self.unique_for_year: |
|---|
| 328 |
params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_year))) |
|---|
| 329 |
if self.unique or (self.primary_key and not rel): |
|---|
| 330 |
params['validator_list'].append(curry(manipulator_validator_unique, self, opts, manipulator)) |
|---|
| 331 |
|
|---|
| 332 |
# Only add is_required=True if the field cannot be blank. Primary keys |
|---|
| 333 |
# are a special case, and fields in a related context should set this |
|---|
| 334 |
# as False, because they'll be caught by a separate validator -- |
|---|
| 335 |
# RequiredIfOtherFieldGiven. |
|---|
| 336 |
params['is_required'] = not self.blank and not self.primary_key and not rel |
|---|
| 337 |
|
|---|
| 338 |
# BooleanFields (CheckboxFields) are a special case. They don't take |
|---|
| 339 |
# is_required. |
|---|
| 340 |
if isinstance(self, BooleanField): |
|---|
| 341 |
del params['is_required'] |
|---|
| 342 |
|
|---|
| 343 |
# If this field is in a related context, check whether any other fields |
|---|
| 344 |
# in the related object have core=True. If so, add a validator -- |
|---|
| 345 |
# RequiredIfOtherFieldsGiven -- to this FormField. |
|---|
| 346 |
if rel and not self.blank and not isinstance(self, AutoField) and not isinstance(self, FileField): |
|---|
| 347 |
# First, get the core fields, if any. |
|---|
| 348 |
core_field_names = [] |
|---|
| 349 |
for f in opts.fields: |
|---|
| 350 |
if f.core and f != self: |
|---|
| 351 |
core_field_names.extend(f.get_manipulator_field_names(name_prefix)) |
|---|
| 352 |
# Now, if there are any, add the validator to this FormField. |
|---|
| 353 |
if core_field_names: |
|---|
| 354 |
params['validator_list'].append(validators.RequiredIfOtherFieldsGiven(core_field_names, ugettext_lazy("This field is required."))) |
|---|
| 355 |
|
|---|
| 356 |
# Finally, add the field_names. |
|---|
| 357 |
field_names = self.get_manipulator_field_names(name_prefix) |
|---|
| 358 |
return [man(field_name=field_names[i], **params) for i, man in enumerate(field_objs)] |
|---|
| 359 |
|
|---|
| 360 |
def get_validator_unique_lookup_type(self): |
|---|
| 361 |
return '%s__exact' % self.name |
|---|
| 362 |
|
|---|
| 363 |
def get_manipulator_new_data(self, new_data, rel=False): |
|---|
| 364 |
""" |
|---|
| 365 |
Given the full new_data dictionary (from the manipulator), returns this |
|---|
| 366 |
field's data. |
|---|
| 367 |
""" |
|---|
| 368 |
if rel: |
|---|
| 369 |
return new_data.get(self.name, [self.get_default()])[0] |
|---|
| 370 |
val = new_data.get(self.name, self.get_default()) |
|---|
| 371 |
if not self.empty_strings_allowed and val == '' and self.null: |
|---|
| 372 |
val = None |
|---|
| 373 |
return val |
|---|
| 374 |
|
|---|
| 375 |
def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH): |
|---|
| 376 |
"Returns a list of tuples used as SelectField choices for this field." |
|---|
| 377 |
first_choice = include_blank and blank_choice or [] |
|---|
| 378 |
if self.choices: |
|---|
| 379 |
return first_choice + list(self.choices) |
|---|
| 380 |
rel_model = self.rel.to |
|---|
| 381 |
if hasattr(self.rel, 'get_related_field'): |
|---|
| 382 |
lst = [(getattr(x, self.rel.get_related_field().attname), smart_unicode(x)) for x in rel_model._default_manager.complex_filter(self.rel.limit_choices_to)] |
|---|
| 383 |
else: |
|---|
| 384 |
lst = [(x._get_pk_val(), smart_unicode(x)) for x in rel_model._default_manager.complex_filter(self.rel.limit_choices_to)] |
|---|
| 385 |
return first_choice + lst |
|---|
| 386 |
|
|---|
| 387 |
def get_choices_default(self): |
|---|
| 388 |
if self.radio_admin: |
|---|
| 389 |
return self.get_choices(include_blank=self.blank, blank_choice=BLANK_CHOICE_NONE) |
|---|
| 390 |
else: |
|---|
| 391 |
return self.get_choices() |
|---|
| 392 |
|
|---|
| 393 |
def _get_val_from_obj(self, obj): |
|---|
| 394 |
if obj: |
|---|
| 395 |
return getattr(obj, self.attname) |
|---|
| 396 |
else: |
|---|
| 397 |
return self.get_default() |
|---|
| 398 |
|
|---|
| 399 |
def flatten_data(self, follow, obj=None): |
|---|
| 400 |
""" |
|---|
| 401 |
Returns a dictionary mapping the field's manipulator field names to its |
|---|
| 402 |
"flattened" string values for the admin view. obj is the instance to |
|---|
| 403 |
extract the values from. |
|---|
| 404 |
""" |
|---|
| 405 |
return {self.attname: self._get_val_from_obj(obj)} |
|---|
| 406 |
|
|---|
| 407 |
def get_follow(self, override=None): |
|---|
| 408 |
if override != None: |
|---|
| 409 |
return override |
|---|
| 410 |
else: |
|---|
| 411 |
return self.editable |
|---|
| 412 |
|
|---|
| 413 |
def bind(self, fieldmapping, original, bound_field_class): |
|---|
| 414 |
return bound_field_class(self, fieldmapping, original) |
|---|
| 415 |
|
|---|
| 416 |
def _get_choices(self): |
|---|
| 417 |
if hasattr(self._choices, 'next'): |
|---|
| 418 |
choices, self._choices = tee(self._choices) |
|---|
| 419 |
return choices |
|---|
| 420 |
else: |
|---|
| 421 |
return self._choices |
|---|
| 422 |
choices = property(_get_choices) |
|---|
| 423 |
|
|---|
| 424 |
def save_form_data(self, instance, data): |
|---|
| 425 |
setattr(instance, self.name, data) |
|---|
| 426 |
|
|---|
| 427 |
def formfield(self, form_class=forms.CharField, **kwargs): |
|---|
| 428 |
"Returns a django.newforms.Field instance for this database Field." |
|---|
| 429 |
defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text} |
|---|
| 430 |
if self.choices: |
|---|
| 431 |
defaults['widget'] = forms.Select(choices=self.get_choices(include_blank=self.blank or not (self.has_default() or 'initial' in kwargs))) |
|---|
| 432 |
if self.has_default(): |
|---|
| 433 |
defaults['initial'] = self.get_default() |
|---|
| 434 |
defaults.update(kwargs) |
|---|
| 435 |
return form_class(**defaults) |
|---|
| 436 |
|
|---|
| 437 |
def value_from_object(self, obj): |
|---|
| 438 |
"Returns the value of this field in the given model instance." |
|---|
| 439 |
return getattr(obj, self.attname) |
|---|
| 440 |
|
|---|
| 441 |
class AutoField(Field): |
|---|
| 442 |
empty_strings_allowed = False |
|---|
| 443 |
def __init__(self, *args, **kwargs): |
|---|
| 444 |
assert kwargs.get('primary_key', False) is True, "%ss must have primary_key=True." % self.__class__.__name__ |
|---|
| 445 |
kwargs['blank'] = True |
|---|
| 446 |
Field.__init__(self, *args, **kwargs) |
|---|
| 447 |
|
|---|
| 448 |
def to_python(self, value): |
|---|
| 449 |
if value is None: |
|---|
| 450 |
return value |
|---|
| 451 |
try: |
|---|
| 452 |
return int(value) |
|---|
| 453 |
except (TypeError, ValueError): |
|---|
| 454 |
raise validators.ValidationError, _("This value must be an integer.") |
|---|
| 455 |
|
|---|
| 456 |
def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True): |
|---|
| 457 |
if not rel: |
|---|
| 458 |
return [] # Don't add a FormField unless it's in a related context. |
|---|
| 459 |
return Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel, follow) |
|---|
| 460 |
|
|---|
| 461 |
def get_manipulator_field_objs(self): |
|---|
| 462 |
return [oldforms.HiddenField] |
|---|
| 463 |
|
|---|
| 464 |
def get_manipulator_new_data(self, new_data, rel=False): |
|---|
| 465 |
# Never going to be called |
|---|
| 466 |
# Not in main change pages |
|---|
| 467 |
# ignored in related context |
|---|
| 468 |
if not rel: |
|---|
| 469 |
return None |
|---|
| 470 |
return Field.get_manipulator_new_data(self, new_data, rel) |
|---|
| 471 |
|
|---|
| 472 |
def contribute_to_class(self, cls, name): |
|---|
| 473 |
assert not cls._meta.has_auto_field, "A model can't have more than one AutoField." |
|---|
| 474 |
super(AutoField, self).contribute_to_class(cls, name) |
|---|
| 475 |
cls._meta.has_auto_field = True |
|---|
| 476 |
cls._meta.auto_field = self |
|---|
| 477 |
|
|---|
| 478 |
def formfield(self, **kwargs): |
|---|
| 479 |
return None |
|---|
| 480 |
|
|---|
| 481 |
class BooleanField(Field): |
|---|
| 482 |
def __init__(self, *args, **kwargs): |
|---|
| 483 |
kwargs['blank'] = True |
|---|
| 484 |
Field.__init__(self, *args, **kwargs) |
|---|
| 485 |
|
|---|
| 486 |
def get_internal_type(self): |
|---|
| 487 |
return "BooleanField" |
|---|
| 488 |
|
|---|
| 489 |
def to_python(self, value): |
|---|
| 490 |
if value in (True, False): return value |
|---|
| 491 |
if value in ('t', 'True', |
|---|