2007-07-20 14:28:56 +08:00
from django . db import get_creation_module
2006-05-02 09:31:56 +08:00
from django . db . models import signals
from django . dispatch import dispatcher
2005-08-02 05:29:52 +08:00
from django . conf import settings
2006-05-02 09:31:56 +08:00
from django . core import validators
2006-12-16 02:00:50 +08:00
from django import oldforms
2006-12-16 02:15:55 +08:00
from django import newforms as forms
2005-08-02 05:29:52 +08:00
from django . core . exceptions import ObjectDoesNotExist
2006-07-22 04:39:17 +08:00
from django . utils . functional import curry
2006-09-26 14:33:32 +08:00
from django . utils . itercompat import tee
2005-08-02 05:29:52 +08:00
from django . utils . text import capfirst
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
from django . utils . translation import ugettext_lazy , ugettext as _
2007-07-06 18:21:14 +08:00
from django . utils . encoding import smart_unicode , force_unicode , smart_str
2007-08-05 13:14:46 +08:00
from django . utils . maxlength import LegacyMaxlength
2006-05-02 09:31:56 +08:00
import datetime , os , time
2007-05-21 09:29:58 +08:00
try :
import decimal
except ImportError :
from django . utils import _decimal as decimal # for Python 2.3
2005-08-02 05:29:52 +08:00
2006-03-01 11:51:55 +08:00
class NOT_PROVIDED :
pass
2005-08-02 05:29:52 +08:00
# Values for filter_interface.
HORIZONTAL , VERTICAL = 1 , 2
# The values to use for "blank" in SelectFields. Will be appended to the start of most "choices" lists.
BLANK_CHOICE_DASH = [ ( " " , " --------- " ) ]
BLANK_CHOICE_NONE = [ ( " " , " None " ) ]
# prepares a value for use in a LIKE query
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
prep_for_like_query = lambda x : smart_unicode ( x ) . replace ( " \\ " , " \\ \\ " ) . replace ( " % " , " \ % " ) . replace ( " _ " , " \ _ " )
2005-08-02 05:29:52 +08:00
# returns the <ul> class for a given radio_admin value
get_ul_class = lambda x : ' radiolist %s ' % ( ( x == HORIZONTAL ) and ' inline ' or ' ' )
2006-05-02 09:31:56 +08:00
class FieldDoesNotExist ( Exception ) :
pass
2005-08-02 05:29:52 +08:00
def manipulator_validator_unique ( f , opts , self , field_data , all_data ) :
" Validates that the value is unique for this field. "
2006-05-02 09:31:56 +08:00
lookup_type = f . get_validator_unique_lookup_type ( )
2005-08-02 05:29:52 +08:00
try :
2006-05-02 09:31:56 +08:00
old_obj = self . manager . get ( * * { lookup_type : field_data } )
2005-08-02 05:29:52 +08:00
except ObjectDoesNotExist :
return
2006-05-02 09:31:56 +08:00
if getattr ( self , ' original_object ' , None ) and self . original_object . _get_pk_val ( ) == old_obj . _get_pk_val ( ) :
2005-08-02 05:29:52 +08:00
return
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
raise validators . ValidationError , _ ( " %(optname)s with this %(fieldname)s already exists. " ) % { ' optname ' : capfirst ( opts . verbose_name ) , ' fieldname ' : f . verbose_name }
2005-11-10 07:37:41 +08:00
# A guide to Field parameters:
#
2006-05-02 09:31:56 +08:00
# * name: The name of the field specifed in the model.
2005-11-10 07:37:41 +08:00
# * attname: The attribute to use on the model object. This is the same as
# "name", except in the case of ForeignKeys, where "_id" is
# appended.
# * db_column: The db_column specified in the model (or None).
# * column: The database column for this field. This is the same as
# "attname", except if db_column is specified.
#
# Code that introspects values, or does other dynamic things, should use
# attname. For example, this gets the primary key value of object "obj":
#
# getattr(obj, opts.pk.attname)
2005-08-02 05:29:52 +08:00
class Field ( object ) :
2007-08-05 13:14:46 +08:00
# Provide backwards compatibility for the maxlength attribute and
# argument for this class and all subclasses.
__metaclass__ = LegacyMaxlength
2005-08-02 05:29:52 +08:00
# Designates whether empty strings fundamentally are allowed at the
# database level.
empty_strings_allowed = True
2005-08-26 06:51:30 +08:00
# Tracks each time a Field instance is created. Used to retain order.
creation_counter = 0
def __init__ ( self , verbose_name = None , name = None , primary_key = False ,
2007-08-05 13:14:46 +08:00
max_length = None , unique = False , blank = False , null = False , db_index = False ,
2007-03-19 19:57:53 +08:00
core = False , rel = None , default = NOT_PROVIDED , editable = True , serialize = True ,
2005-08-02 05:29:52 +08:00
prepopulate_from = None , unique_for_date = None , unique_for_month = None ,
unique_for_year = None , validator_list = None , choices = None , radio_admin = None ,
2007-06-23 22:16:00 +08:00
help_text = ' ' , db_column = None , db_tablespace = None ) :
2005-08-02 05:29:52 +08:00
self . name = name
2006-05-02 09:31:56 +08:00
self . verbose_name = verbose_name
2005-08-02 05:29:52 +08:00
self . primary_key = primary_key
2007-08-05 13:14:46 +08:00
self . max_length , self . unique = max_length , unique
2005-08-02 05:29:52 +08:00
self . blank , self . null = blank , null
2007-06-23 22:16:00 +08:00
# Oracle treats the empty string ('') as null, so coerce the null
# option whenever '' is a possible value.
if self . empty_strings_allowed and settings . DATABASE_ENGINE == ' oracle ' :
self . null = True
2005-08-02 05:29:52 +08:00
self . core , self . rel , self . default = core , rel , default
self . editable = editable
2007-03-19 19:57:53 +08:00
self . serialize = serialize
2005-08-02 05:29:52 +08:00
self . validator_list = validator_list or [ ]
self . prepopulate_from = prepopulate_from
self . unique_for_date , self . unique_for_month = unique_for_date , unique_for_month
self . unique_for_year = unique_for_year
2006-09-26 14:33:32 +08:00
self . _choices = choices or [ ]
2005-08-02 05:29:52 +08:00
self . radio_admin = radio_admin
self . help_text = help_text
2005-08-26 06:51:30 +08:00
self . db_column = db_column
2007-06-23 22:16:00 +08:00
self . db_tablespace = db_tablespace
2005-08-02 05:29:52 +08:00
# Set db_index to True if the field has a relationship and doesn't explicitly set db_index.
2006-05-02 09:31:56 +08:00
self . db_index = db_index
2005-08-02 05:29:52 +08:00
2005-08-26 06:51:30 +08:00
# Increase the creation counter, and save our local copy.
self . creation_counter = Field . creation_counter
Field . creation_counter + = 1
2006-05-02 09:31:56 +08:00
def __cmp__ ( self , other ) :
# This is needed because bisect does not take a comparison function.
return cmp ( self . creation_counter , other . creation_counter )
def to_python ( self , value ) :
"""
Converts the input value into the expected Python data type , raising
validators . ValidationError if the data can ' t be converted. Returns the
converted value . Subclasses should override this .
"""
return value
2007-07-20 14:28:56 +08:00
def db_type ( self ) :
"""
Returns the database column data type for this field , taking into
account the DATABASE_ENGINE setting .
"""
# The default implementation of this method looks at the
# backend-specific DATA_TYPES dictionary, looking up the field by its
# "internal type".
#
# A Field class can implement the get_internal_type() method to specify
# which *preexisting* Django Field class it's most similar to -- i.e.,
# an XMLField is represented by a TEXT column type, which is the same
# as the TextField Django field type, which means XMLField's
# get_internal_type() returns 'TextField'.
#
# But the limitation of the get_internal_type() / DATA_TYPES approach
# is that it cannot handle database column types that aren't already
# mapped to one of the built-in Django field types. In this case, you
# can implement db_type() instead of get_internal_type() to specify
# exactly which wacky database column type you want to use.
data_types = get_creation_module ( ) . DATA_TYPES
internal_type = self . get_internal_type ( )
return data_types [ internal_type ] % self . __dict__
2006-05-02 09:31:56 +08:00
def validate_full ( self , field_data , all_data ) :
"""
Returns a list of errors for this field . This is the main interface ,
as it encapsulates some basic validation logic used by all fields .
Subclasses should implement validate ( ) , not validate_full ( ) .
"""
if not self . blank and not field_data :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
return [ _ ( ' This field is required. ' ) ]
2006-05-02 09:31:56 +08:00
try :
self . validate ( field_data , all_data )
except validators . ValidationError , e :
return e . messages
return [ ]
def validate ( self , field_data , all_data ) :
"""
Raises validators . ValidationError if field_data has any errors .
Subclasses should override this to specify field - specific validation
logic . This method should assume field_data has already been converted
into the appropriate data type by Field . to_python ( ) .
"""
pass
def set_attributes_from_name ( self , name ) :
self . name = name
2005-11-10 07:37:41 +08:00
self . attname , self . column = self . get_attname_column ( )
2006-05-02 09:31:56 +08:00
self . verbose_name = self . verbose_name or ( name and name . replace ( ' _ ' , ' ' ) )
def contribute_to_class ( self , cls , name ) :
self . set_attributes_from_name ( name )
cls . _meta . add_field ( self )
if self . choices :
setattr ( cls , ' get_ %s _display ' % self . name , curry ( cls . _get_FIELD_display , field = self ) )
2005-08-26 06:51:30 +08:00
2006-05-02 09:31:56 +08:00
def get_attname ( self ) :
return self . name
2005-11-10 07:37:41 +08:00
def get_attname_column ( self ) :
2006-05-02 09:31:56 +08:00
attname = self . get_attname ( )
2005-11-10 07:37:41 +08:00
column = self . db_column or attname
return attname , column
2005-08-26 06:51:30 +08:00
def get_cache_name ( self ) :
return ' _ %s _cache ' % self . name
2005-09-29 07:08:47 +08:00
def get_internal_type ( self ) :
return self . __class__ . __name__
2006-05-30 01:08:58 +08:00
def pre_save ( self , model_instance , add ) :
2005-08-10 13:08:27 +08:00
" Returns field ' s value just before saving. "
2006-05-30 01:08:58 +08:00
return getattr ( model_instance , self . attname )
2005-08-02 05:29:52 +08:00
2005-08-10 11:12:37 +08:00
def get_db_prep_save ( self , value ) :
2005-08-02 05:29:52 +08:00
" Returns field ' s value prepared for saving into a database. "
return value
def get_db_prep_lookup ( self , lookup_type , value ) :
" Returns field ' s value prepared for database lookup. "
2007-06-28 02:58:10 +08:00
if lookup_type in ( ' exact ' , ' regex ' , ' iregex ' , ' gt ' , ' gte ' , ' lt ' , ' lte ' , ' month ' , ' day ' , ' search ' ) :
2005-08-02 05:29:52 +08:00
return [ value ]
elif lookup_type in ( ' range ' , ' in ' ) :
return value
2005-12-05 02:54:44 +08:00
elif lookup_type in ( ' contains ' , ' icontains ' ) :
2005-08-02 05:29:52 +08:00
return [ " %% %s %% " % prep_for_like_query ( value ) ]
elif lookup_type == ' iexact ' :
return [ prep_for_like_query ( value ) ]
2005-12-05 02:54:44 +08:00
elif lookup_type in ( ' startswith ' , ' istartswith ' ) :
2005-08-02 05:29:52 +08:00
return [ " %s %% " % prep_for_like_query ( value ) ]
2005-12-05 02:54:44 +08:00
elif lookup_type in ( ' endswith ' , ' iendswith ' ) :
2005-08-02 05:29:52 +08:00
return [ " %% %s " % prep_for_like_query ( value ) ]
elif lookup_type == ' isnull ' :
return [ ]
2007-02-14 14:32:32 +08:00
elif lookup_type == ' year ' :
try :
value = int ( value )
except ValueError :
raise ValueError ( " The __year lookup type requires an integer argument " )
return [ ' %s -01-01 00:00:00 ' % value , ' %s -12-31 23:59:59.999999 ' % value ]
raise TypeError ( " Field has invalid lookup: %s " % lookup_type )
2005-08-02 05:29:52 +08:00
def has_default ( self ) :
" Returns a boolean of whether this field has a default value. "
2006-03-01 11:51:55 +08:00
return self . default is not NOT_PROVIDED
2005-08-02 05:29:52 +08:00
def get_default ( self ) :
" Returns the default value for this field. "
2006-03-01 11:51:55 +08:00
if self . default is not NOT_PROVIDED :
2006-05-02 09:31:56 +08:00
if callable ( self . default ) :
return self . default ( )
2005-08-02 05:29:52 +08:00
return self . default
2007-06-23 22:16:00 +08:00
if not self . empty_strings_allowed or ( self . null and settings . DATABASE_ENGINE != ' oracle ' ) :
2005-08-02 05:29:52 +08:00
return None
return " "
def get_manipulator_field_names ( self , name_prefix ) :
"""
Returns a list of field names that this object adds to the manipulator .
"""
return [ name_prefix + self . name ]
2006-05-02 09:31:56 +08:00
def prepare_field_objs_and_params ( self , manipulator , name_prefix ) :
2005-08-02 05:29:52 +08:00
params = { ' validator_list ' : self . validator_list [ : ] }
2007-08-05 13:14:46 +08:00
if self . max_length and not self . choices : # Don't give SelectFields a max_length parameter.
params [ ' max_length ' ] = self . max_length
2006-05-02 09:31:56 +08:00
if self . choices :
2005-08-02 05:29:52 +08:00
if self . radio_admin :
2006-12-16 02:00:50 +08:00
field_objs = [ oldforms . RadioSelectField ]
2005-08-02 05:29:52 +08:00
params [ ' ul_class ' ] = get_ul_class ( self . radio_admin )
else :
2006-12-16 02:00:50 +08:00
field_objs = [ oldforms . SelectField ]
2005-11-26 05:20:09 +08:00
params [ ' choices ' ] = self . get_choices_default ( )
2005-08-02 05:29:52 +08:00
else :
field_objs = self . get_manipulator_field_objs ( )
2006-05-02 09:31:56 +08:00
return ( field_objs , params )
def get_manipulator_fields ( self , opts , manipulator , change , name_prefix = ' ' , rel = False , follow = True ) :
"""
2006-12-16 02:00:50 +08:00
Returns a list of oldforms . FormField instances for this field . It
2006-05-02 09:31:56 +08:00
calculates the choices at runtime , not at compile time .
name_prefix is a prefix to prepend to the " field_name " argument .
rel is a boolean specifying whether this field is in a related context .
"""
field_objs , params = self . prepare_field_objs_and_params ( manipulator , name_prefix )
2005-08-02 05:29:52 +08:00
# Add the "unique" validator(s).
for field_name_list in opts . unique_together :
if field_name_list [ 0 ] == self . name :
params [ ' validator_list ' ] . append ( getattr ( manipulator , ' isUnique %s ' % ' _ ' . join ( field_name_list ) ) )
# Add the "unique for..." validator(s).
if self . unique_for_date :
params [ ' validator_list ' ] . append ( getattr ( manipulator , ' isUnique %s For %s ' % ( self . name , self . unique_for_date ) ) )
if self . unique_for_month :
params [ ' validator_list ' ] . append ( getattr ( manipulator , ' isUnique %s For %s ' % ( self . name , self . unique_for_month ) ) )
if self . unique_for_year :
params [ ' validator_list ' ] . append ( getattr ( manipulator , ' isUnique %s For %s ' % ( self . name , self . unique_for_year ) ) )
2005-08-11 03:32:38 +08:00
if self . unique or ( self . primary_key and not rel ) :
2005-08-02 05:29:52 +08:00
params [ ' validator_list ' ] . append ( curry ( manipulator_validator_unique , self , opts , manipulator ) )
# Only add is_required=True if the field cannot be blank. Primary keys
# are a special case, and fields in a related context should set this
# as False, because they'll be caught by a separate validator --
# RequiredIfOtherFieldGiven.
params [ ' is_required ' ] = not self . blank and not self . primary_key and not rel
2006-05-02 09:31:56 +08:00
# BooleanFields (CheckboxFields) are a special case. They don't take
2006-07-28 08:13:10 +08:00
# is_required.
2006-05-02 09:31:56 +08:00
if isinstance ( self , BooleanField ) :
2006-07-28 08:13:10 +08:00
del params [ ' is_required ' ]
2006-05-02 09:31:56 +08:00
2005-08-02 05:29:52 +08:00
# If this field is in a related context, check whether any other fields
# in the related object have core=True. If so, add a validator --
# RequiredIfOtherFieldsGiven -- to this FormField.
if rel and not self . blank and not isinstance ( self , AutoField ) and not isinstance ( self , FileField ) :
# First, get the core fields, if any.
core_field_names = [ ]
for f in opts . fields :
if f . core and f != self :
core_field_names . extend ( f . get_manipulator_field_names ( name_prefix ) )
# Now, if there are any, add the validator to this FormField.
if core_field_names :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
params [ ' validator_list ' ] . append ( validators . RequiredIfOtherFieldsGiven ( core_field_names , ugettext_lazy ( " This field is required. " ) ) )
2005-08-02 05:29:52 +08:00
# Finally, add the field_names.
field_names = self . get_manipulator_field_names ( name_prefix )
return [ man ( field_name = field_names [ i ] , * * params ) for i , man in enumerate ( field_objs ) ]
2006-05-02 09:31:56 +08:00
def get_validator_unique_lookup_type ( self ) :
return ' %s __exact ' % self . name
2005-08-02 05:29:52 +08:00
def get_manipulator_new_data ( self , new_data , rel = False ) :
"""
Given the full new_data dictionary ( from the manipulator ) , returns this
field ' s data.
"""
if rel :
return new_data . get ( self . name , [ self . get_default ( ) ] ) [ 0 ]
2006-05-02 09:31:56 +08:00
val = new_data . get ( self . name , self . get_default ( ) )
if not self . empty_strings_allowed and val == ' ' and self . null :
val = None
return val
2005-08-02 05:29:52 +08:00
def get_choices ( self , include_blank = True , blank_choice = BLANK_CHOICE_DASH ) :
" Returns a list of tuples used as SelectField choices for this field. "
first_choice = include_blank and blank_choice or [ ]
if self . choices :
return first_choice + list ( self . choices )
2006-05-02 09:31:56 +08:00
rel_model = self . rel . to
2006-08-01 22:20:01 +08:00
if hasattr ( self . rel , ' get_related_field ' ) :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
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 ) ]
2006-08-01 22:20:01 +08:00
else :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
lst = [ ( x . _get_pk_val ( ) , smart_unicode ( x ) ) for x in rel_model . _default_manager . complex_filter ( self . rel . limit_choices_to ) ]
2006-08-01 22:20:01 +08:00
return first_choice + lst
2005-11-26 05:20:09 +08:00
def get_choices_default ( self ) :
2006-05-02 09:31:56 +08:00
if self . radio_admin :
2005-11-26 05:20:09 +08:00
return self . get_choices ( include_blank = self . blank , blank_choice = BLANK_CHOICE_NONE )
else :
return self . get_choices ( )
def _get_val_from_obj ( self , obj ) :
if obj :
2006-05-02 09:31:56 +08:00
return getattr ( obj , self . attname )
2005-11-26 05:20:09 +08:00
else :
2006-05-02 09:31:56 +08:00
return self . get_default ( )
2005-11-26 05:20:09 +08:00
2005-12-09 10:15:54 +08:00
def flatten_data ( self , follow , obj = None ) :
2005-11-26 05:20:09 +08:00
"""
Returns a dictionary mapping the field ' s manipulator field names to its
" flattened " string values for the admin view . obj is the instance to
extract the values from .
"""
return { self . attname : self . _get_val_from_obj ( obj ) }
def get_follow ( self , override = None ) :
if override != None :
return override
else :
return self . editable
2006-05-02 09:31:56 +08:00
def bind ( self , fieldmapping , original , bound_field_class ) :
2005-11-26 05:20:09 +08:00
return bound_field_class ( self , fieldmapping , original )
2005-08-02 05:29:52 +08:00
2006-09-26 14:33:32 +08:00
def _get_choices ( self ) :
if hasattr ( self . _choices , ' next ' ) :
choices , self . _choices = tee ( self . _choices )
return choices
else :
return self . _choices
choices = property ( _get_choices )
2007-04-28 21:55:24 +08:00
def formfield ( self , form_class = forms . CharField , * * kwargs ) :
2006-12-15 13:46:11 +08:00
" Returns a django.newforms.Field instance for this database Field. "
2007-01-29 06:36:02 +08:00
defaults = { ' required ' : not self . blank , ' label ' : capfirst ( self . verbose_name ) , ' help_text ' : self . help_text }
2007-04-28 22:18:03 +08:00
if self . choices :
defaults [ ' widget ' ] = forms . Select ( choices = self . get_choices ( ) )
2007-01-22 14:32:14 +08:00
defaults . update ( kwargs )
2007-04-28 21:55:24 +08:00
return form_class ( * * defaults )
2006-12-15 13:46:11 +08:00
2006-12-28 10:27:14 +08:00
def value_from_object ( self , obj ) :
" Returns the value of this field in the given model instance. "
return getattr ( obj , self . attname )
2005-08-02 05:29:52 +08:00
class AutoField ( Field ) :
empty_strings_allowed = False
2005-08-10 13:08:27 +08:00
def __init__ ( self , * args , * * kwargs ) :
assert kwargs . get ( ' primary_key ' , False ) is True , " %s s must have primary_key=True. " % self . __class__ . __name__
2006-05-02 09:31:56 +08:00
kwargs [ ' blank ' ] = True
2005-08-10 13:08:27 +08:00
Field . __init__ ( self , * args , * * kwargs )
2006-05-02 09:31:56 +08:00
def to_python ( self , value ) :
if value is None :
return value
try :
return int ( value )
except ( TypeError , ValueError ) :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
raise validators . ValidationError , _ ( " This value must be an integer. " )
2006-05-02 09:31:56 +08:00
def get_manipulator_fields ( self , opts , manipulator , change , name_prefix = ' ' , rel = False , follow = True ) :
2005-08-02 05:29:52 +08:00
if not rel :
return [ ] # Don't add a FormField unless it's in a related context.
2006-05-02 09:31:56 +08:00
return Field . get_manipulator_fields ( self , opts , manipulator , change , name_prefix , rel , follow )
2005-08-02 05:29:52 +08:00
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . HiddenField ]
2005-08-02 05:29:52 +08:00
def get_manipulator_new_data ( self , new_data , rel = False ) :
2006-05-02 09:31:56 +08:00
# Never going to be called
# Not in main change pages
# ignored in related context
2005-08-02 05:29:52 +08:00
if not rel :
return None
return Field . get_manipulator_new_data ( self , new_data , rel )
2006-05-02 09:31:56 +08:00
def contribute_to_class ( self , cls , name ) :
assert not cls . _meta . has_auto_field , " A model can ' t have more than one AutoField. "
super ( AutoField , self ) . contribute_to_class ( cls , name )
cls . _meta . has_auto_field = True
2007-01-22 14:32:14 +08:00
def formfield ( self , * * kwargs ) :
2006-12-16 05:22:13 +08:00
return None
2005-08-02 05:29:52 +08:00
class BooleanField ( Field ) :
def __init__ ( self , * args , * * kwargs ) :
kwargs [ ' blank ' ] = True
Field . __init__ ( self , * args , * * kwargs )
2006-05-02 09:31:56 +08:00
def to_python ( self , value ) :
if value in ( True , False ) : return value
2006-09-26 08:36:04 +08:00
if value in ( ' t ' , ' True ' , ' 1 ' ) : return True
if value in ( ' f ' , ' False ' , ' 0 ' ) : return False
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
raise validators . ValidationError , _ ( " This value must be either True or False. " )
2006-05-02 09:31:56 +08:00
2005-08-02 05:29:52 +08:00
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . CheckboxField ]
2005-08-02 05:29:52 +08:00
2007-01-22 14:32:14 +08:00
def formfield ( self , * * kwargs ) :
2007-04-28 21:55:24 +08:00
defaults = { ' form_class ' : forms . BooleanField }
2007-01-22 14:32:14 +08:00
defaults . update ( kwargs )
2007-04-28 21:55:24 +08:00
return super ( BooleanField , self ) . formfield ( * * defaults )
2006-12-16 02:32:42 +08:00
2005-08-02 05:29:52 +08:00
class CharField ( Field ) :
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . TextField ]
2006-05-02 09:31:56 +08:00
def to_python ( self , value ) :
if isinstance ( value , basestring ) :
return value
if value is None :
if self . null :
return value
else :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
raise validators . ValidationError , ugettext_lazy ( " This field cannot be null. " )
return smart_unicode ( value )
2005-08-02 05:29:52 +08:00
2007-01-22 14:32:14 +08:00
def formfield ( self , * * kwargs ) :
2007-08-05 13:14:46 +08:00
defaults = { ' max_length ' : self . max_length }
2007-01-22 14:32:14 +08:00
defaults . update ( kwargs )
2007-04-28 21:55:24 +08:00
return super ( CharField , self ) . formfield ( * * defaults )
2006-12-16 02:32:42 +08:00
2006-05-02 09:31:56 +08:00
# TODO: Maybe move this into contrib, because it's specialized.
2005-08-02 05:29:52 +08:00
class CommaSeparatedIntegerField ( CharField ) :
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . CommaSeparatedIntegerField ]
2005-08-02 05:29:52 +08:00
class DateField ( Field ) :
empty_strings_allowed = False
2005-08-26 06:51:30 +08:00
def __init__ ( self , verbose_name = None , name = None , auto_now = False , auto_now_add = False , * * kwargs ) :
2005-08-02 05:29:52 +08:00
self . auto_now , self . auto_now_add = auto_now , auto_now_add
2006-05-02 09:31:56 +08:00
#HACKs : auto_now_add/auto_now should be done as a default or a pre_save.
2005-08-02 05:29:52 +08:00
if auto_now or auto_now_add :
kwargs [ ' editable ' ] = False
2005-11-26 05:20:09 +08:00
kwargs [ ' blank ' ] = True
2005-08-26 06:51:30 +08:00
Field . __init__ ( self , verbose_name , name , * * kwargs )
2005-08-02 05:29:52 +08:00
2006-05-02 09:31:56 +08:00
def to_python ( self , value ) :
2007-02-26 13:07:12 +08:00
if value is None :
return value
2006-05-02 09:31:56 +08:00
if isinstance ( value , datetime . datetime ) :
return value . date ( )
if isinstance ( value , datetime . date ) :
return value
validators . isValidANSIDate ( value , None )
2006-07-01 02:57:23 +08:00
try :
return datetime . date ( * time . strptime ( value , ' % Y- % m- %d ' ) [ : 3 ] )
except ValueError :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
raise validators . ValidationError , _ ( ' Enter a valid date in YYYY-MM-DD format. ' )
2006-05-02 09:31:56 +08:00
2005-08-02 05:29:52 +08:00
def get_db_prep_lookup ( self , lookup_type , value ) :
if lookup_type == ' range ' :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
value = [ smart_unicode ( v ) for v in value ]
2006-07-01 13:41:48 +08:00
elif lookup_type in ( ' exact ' , ' gt ' , ' gte ' , ' lt ' , ' lte ' ) and hasattr ( value , ' strftime ' ) :
2006-05-02 09:31:56 +08:00
value = value . strftime ( ' % Y- % m- %d ' )
2005-08-02 05:29:52 +08:00
else :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
value = smart_unicode ( value )
2005-08-02 05:29:52 +08:00
return Field . get_db_prep_lookup ( self , lookup_type , value )
2006-05-30 01:08:58 +08:00
def pre_save ( self , model_instance , add ) :
2005-08-10 11:50:46 +08:00
if self . auto_now or ( self . auto_now_add and add ) :
2006-05-30 01:08:58 +08:00
value = datetime . datetime . now ( )
setattr ( model_instance , self . attname , value )
return value
else :
return super ( DateField , self ) . pre_save ( model_instance , add )
2005-08-02 05:29:52 +08:00
2006-05-02 09:31:56 +08:00
def contribute_to_class ( self , cls , name ) :
super ( DateField , self ) . contribute_to_class ( cls , name )
if not self . null :
setattr ( cls , ' get_next_by_ %s ' % self . name ,
curry ( cls . _get_next_or_previous_by_FIELD , field = self , is_next = True ) )
setattr ( cls , ' get_previous_by_ %s ' % self . name ,
curry ( cls . _get_next_or_previous_by_FIELD , field = self , is_next = False ) )
2005-11-26 05:20:09 +08:00
# Needed because of horrible auto_now[_add] behaviour wrt. editable
def get_follow ( self , override = None ) :
if override != None :
return override
else :
return self . editable or self . auto_now or self . auto_now_add
2005-08-10 11:12:37 +08:00
def get_db_prep_save ( self , value ) :
2005-08-02 05:29:52 +08:00
# Casts dates into string format for entry into database.
2006-11-26 10:38:04 +08:00
if value is not None :
2005-08-02 05:29:52 +08:00
value = value . strftime ( ' % Y- % m- %d ' )
2005-08-10 11:12:37 +08:00
return Field . get_db_prep_save ( self , value )
2005-08-02 05:29:52 +08:00
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . DateField ]
2005-08-02 05:29:52 +08:00
2006-12-28 10:20:29 +08:00
def flatten_data ( self , follow , obj = None ) :
2005-11-26 05:20:09 +08:00
val = self . _get_val_from_obj ( obj )
return { self . attname : ( val is not None and val . strftime ( " % Y- % m- %d " ) or ' ' ) }
2007-01-22 14:32:14 +08:00
def formfield ( self , * * kwargs ) :
2007-04-28 21:55:24 +08:00
defaults = { ' form_class ' : forms . DateField }
2007-01-22 14:32:14 +08:00
defaults . update ( kwargs )
2007-04-28 21:55:24 +08:00
return super ( DateField , self ) . formfield ( * * defaults )
2006-12-16 02:32:42 +08:00
2005-08-02 05:29:52 +08:00
class DateTimeField ( DateField ) :
2006-05-02 09:31:56 +08:00
def to_python ( self , value ) :
2007-02-26 13:07:12 +08:00
if value is None :
return value
2006-05-02 09:31:56 +08:00
if isinstance ( value , datetime . datetime ) :
return value
if isinstance ( value , datetime . date ) :
return datetime . datetime ( value . year , value . month , value . day )
try : # Seconds are optional, so try converting seconds first.
return datetime . datetime ( * time . strptime ( value , ' % Y- % m- %d % H: % M: % S ' ) [ : 6 ] )
except ValueError :
try : # Try without seconds.
return datetime . datetime ( * time . strptime ( value , ' % Y- % m- %d % H: % M ' ) [ : 5 ] )
except ValueError : # Try without hour/minutes/seconds.
try :
return datetime . datetime ( * time . strptime ( value , ' % Y- % m- %d ' ) [ : 3 ] )
except ValueError :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
raise validators . ValidationError , _ ( ' Enter a valid date/time in YYYY-MM-DD HH:MM format. ' )
2006-05-02 09:31:56 +08:00
2005-08-10 11:12:37 +08:00
def get_db_prep_save ( self , value ) :
2005-08-02 05:29:52 +08:00
# Casts dates into string format for entry into database.
2006-11-26 10:38:04 +08:00
if value is not None :
2005-08-15 09:03:39 +08:00
# MySQL will throw a warning if microseconds are given, because it
# doesn't support microseconds.
2006-06-21 12:13:48 +08:00
if settings . DATABASE_ENGINE == ' mysql ' and hasattr ( value , ' microsecond ' ) :
2005-08-15 09:03:39 +08:00
value = value . replace ( microsecond = 0 )
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
value = smart_unicode ( value )
2005-08-10 11:12:37 +08:00
return Field . get_db_prep_save ( self , value )
2005-08-02 05:29:52 +08:00
2006-05-02 09:31:56 +08:00
def get_db_prep_lookup ( self , lookup_type , value ) :
if lookup_type == ' range ' :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
value = [ smart_unicode ( v ) for v in value ]
2006-05-02 09:31:56 +08:00
else :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
value = smart_unicode ( value )
2006-05-02 09:31:56 +08:00
return Field . get_db_prep_lookup ( self , lookup_type , value )
2005-08-02 05:29:52 +08:00
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . DateField , oldforms . TimeField ]
2005-08-02 05:29:52 +08:00
def get_manipulator_field_names ( self , name_prefix ) :
return [ name_prefix + self . name + ' _date ' , name_prefix + self . name + ' _time ' ]
def get_manipulator_new_data ( self , new_data , rel = False ) :
date_field , time_field = self . get_manipulator_field_names ( ' ' )
if rel :
d = new_data . get ( date_field , [ None ] ) [ 0 ]
t = new_data . get ( time_field , [ None ] ) [ 0 ]
else :
d = new_data . get ( date_field , None )
t = new_data . get ( time_field , None )
if d is not None and t is not None :
return datetime . datetime . combine ( d , t )
return self . get_default ( )
2005-11-26 05:20:09 +08:00
def flatten_data ( self , follow , obj = None ) :
val = self . _get_val_from_obj ( obj )
date_field , time_field = self . get_manipulator_field_names ( ' ' )
return { date_field : ( val is not None and val . strftime ( " % Y- % m- %d " ) or ' ' ) ,
time_field : ( val is not None and val . strftime ( " % H: % M: % S " ) or ' ' ) }
2007-01-22 14:32:14 +08:00
def formfield ( self , * * kwargs ) :
2007-04-28 21:55:24 +08:00
defaults = { ' form_class ' : forms . DateTimeField }
2007-01-22 14:32:14 +08:00
defaults . update ( kwargs )
2007-04-28 21:55:24 +08:00
return super ( DateTimeField , self ) . formfield ( * * defaults )
2006-12-16 02:32:42 +08:00
2007-05-21 09:29:58 +08:00
class DecimalField ( Field ) :
empty_strings_allowed = False
def __init__ ( self , verbose_name = None , name = None , max_digits = None , decimal_places = None , * * kwargs ) :
self . max_digits , self . decimal_places = max_digits , decimal_places
Field . __init__ ( self , verbose_name , name , * * kwargs )
def to_python ( self , value ) :
if value is None :
return value
try :
return decimal . Decimal ( value )
except decimal . InvalidOperation :
2007-07-31 01:25:35 +08:00
raise validators . ValidationError (
_ ( " This value must be a decimal number. " ) )
2007-05-21 09:29:58 +08:00
def _format ( self , value ) :
if isinstance ( value , basestring ) :
return value
else :
return self . format_number ( value )
def format_number ( self , value ) :
"""
Formats a number into a string with the requisite number of digits and
decimal places .
"""
num_chars = self . max_digits
# Allow for a decimal point
if self . decimal_places > 0 :
num_chars + = 1
# Allow for a minus sign
if value < 0 :
num_chars + = 1
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
return u " %.*f " % ( self . decimal_places , value )
2007-05-21 09:29:58 +08:00
def get_db_prep_save ( self , value ) :
if value is not None :
value = self . _format ( value )
return super ( DecimalField , self ) . get_db_prep_save ( value )
def get_db_prep_lookup ( self , lookup_type , value ) :
if lookup_type == ' range ' :
value = [ self . _format ( v ) for v in value ]
else :
value = self . _format ( value )
return super ( DecimalField , self ) . get_db_prep_lookup ( lookup_type , value )
def get_manipulator_field_objs ( self ) :
return [ curry ( oldforms . DecimalField , max_digits = self . max_digits , decimal_places = self . decimal_places ) ]
def formfield ( self , * * kwargs ) :
defaults = {
' max_digits ' : self . max_digits ,
' decimal_places ' : self . decimal_places ,
' form_class ' : forms . DecimalField ,
}
defaults . update ( kwargs )
return super ( DecimalField , self ) . formfield ( * * defaults )
2006-05-02 09:31:56 +08:00
class EmailField ( CharField ) :
2005-11-21 06:41:41 +08:00
def __init__ ( self , * args , * * kwargs ) :
2007-08-05 13:14:46 +08:00
kwargs [ ' max_length ' ] = 75
2006-05-02 09:31:56 +08:00
CharField . __init__ ( self , * args , * * kwargs )
2005-11-21 06:41:41 +08:00
def get_internal_type ( self ) :
return " CharField "
2005-08-02 05:29:52 +08:00
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . EmailField ]
2006-05-02 09:31:56 +08:00
def validate ( self , field_data , all_data ) :
validators . isValidEmail ( field_data , all_data )
2005-08-02 05:29:52 +08:00
2007-01-22 14:32:14 +08:00
def formfield ( self , * * kwargs ) :
2007-04-28 21:55:24 +08:00
defaults = { ' form_class ' : forms . EmailField }
2007-01-22 14:32:14 +08:00
defaults . update ( kwargs )
2007-04-28 21:55:24 +08:00
return super ( EmailField , self ) . formfield ( * * defaults )
2006-12-16 02:32:42 +08:00
2005-08-02 05:29:52 +08:00
class FileField ( Field ) :
2005-08-26 06:51:30 +08:00
def __init__ ( self , verbose_name = None , name = None , upload_to = ' ' , * * kwargs ) :
2005-08-02 05:29:52 +08:00
self . upload_to = upload_to
2005-08-26 06:51:30 +08:00
Field . __init__ ( self , verbose_name , name , * * kwargs )
2005-08-02 05:29:52 +08:00
2006-05-02 09:31:56 +08:00
def get_manipulator_fields ( self , opts , manipulator , change , name_prefix = ' ' , rel = False , follow = True ) :
field_list = Field . get_manipulator_fields ( self , opts , manipulator , change , name_prefix , rel , follow )
2005-08-02 05:29:52 +08:00
if not self . blank :
if rel :
# This validator makes sure FileFields work in a related context.
2006-06-08 13:00:13 +08:00
class RequiredFileField ( object ) :
2005-08-02 05:29:52 +08:00
def __init__ ( self , other_field_names , other_file_field_name ) :
self . other_field_names = other_field_names
self . other_file_field_name = other_file_field_name
self . always_test = True
def __call__ ( self , field_data , all_data ) :
if not all_data . get ( self . other_file_field_name , False ) :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
c = validators . RequiredIfOtherFieldsGiven ( self . other_field_names , ugettext_lazy ( " This field is required. " ) )
2005-08-02 05:29:52 +08:00
c ( field_data , all_data )
# First, get the core fields, if any.
core_field_names = [ ]
for f in opts . fields :
if f . core and f != self :
core_field_names . extend ( f . get_manipulator_field_names ( name_prefix ) )
# Now, if there are any, add the validator to this FormField.
if core_field_names :
field_list [ 0 ] . validator_list . append ( RequiredFileField ( core_field_names , field_list [ 1 ] . field_name ) )
else :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
v = validators . RequiredIfOtherFieldNotGiven ( field_list [ 1 ] . field_name , ugettext_lazy ( " This field is required. " ) )
2005-08-02 05:29:52 +08:00
v . always_test = True
field_list [ 0 ] . validator_list . append ( v )
field_list [ 0 ] . is_required = field_list [ 1 ] . is_required = False
# If the raw path is passed in, validate it's under the MEDIA_ROOT.
def isWithinMediaRoot ( field_data , all_data ) :
f = os . path . abspath ( os . path . join ( settings . MEDIA_ROOT , field_data ) )
2006-11-07 10:25:49 +08:00
if not f . startswith ( os . path . abspath ( os . path . normpath ( settings . MEDIA_ROOT ) ) ) :
2007-02-12 07:50:35 +08:00
raise validators . ValidationError , _ ( " Enter a valid filename. " )
2005-08-02 05:29:52 +08:00
field_list [ 1 ] . validator_list . append ( isWithinMediaRoot )
return field_list
2006-05-02 09:31:56 +08:00
def contribute_to_class ( self , cls , name ) :
super ( FileField , self ) . contribute_to_class ( cls , name )
setattr ( cls , ' get_ %s _filename ' % self . name , curry ( cls . _get_FIELD_filename , field = self ) )
setattr ( cls , ' get_ %s _url ' % self . name , curry ( cls . _get_FIELD_url , field = self ) )
setattr ( cls , ' get_ %s _size ' % self . name , curry ( cls . _get_FIELD_size , field = self ) )
2007-02-27 01:17:11 +08:00
setattr ( cls , ' save_ %s _file ' % self . name , lambda instance , filename , raw_contents , save = True : instance . _save_FIELD_file ( self , filename , raw_contents , save ) )
2006-05-02 09:31:56 +08:00
dispatcher . connect ( self . delete_file , signal = signals . post_delete , sender = cls )
def delete_file ( self , instance ) :
if getattr ( instance , self . attname ) :
file_name = getattr ( instance , ' get_ %s _filename ' % self . name ) ( )
# If the file exists and no other object of this type references it,
# delete it from the filesystem.
if os . path . exists ( file_name ) and \
not instance . __class__ . _default_manager . filter ( * * { ' %s __exact ' % self . name : getattr ( instance , self . attname ) } ) :
os . remove ( file_name )
2005-08-02 05:29:52 +08:00
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . FileUploadField , oldforms . HiddenField ]
2005-08-02 05:29:52 +08:00
def get_manipulator_field_names ( self , name_prefix ) :
return [ name_prefix + self . name + ' _file ' , name_prefix + self . name ]
2007-02-27 01:17:11 +08:00
def save_file ( self , new_data , new_object , original_object , change , rel , save = True ) :
2005-08-02 05:29:52 +08:00
upload_field_name = self . get_manipulator_field_names ( ' ' ) [ 0 ]
if new_data . get ( upload_field_name , False ) :
2005-12-10 13:32:05 +08:00
func = getattr ( new_object , ' save_ %s _file ' % self . name )
2005-08-02 05:29:52 +08:00
if rel :
2007-02-27 01:17:11 +08:00
func ( new_data [ upload_field_name ] [ 0 ] [ " filename " ] , new_data [ upload_field_name ] [ 0 ] [ " content " ] , save )
2005-08-02 05:29:52 +08:00
else :
2007-02-27 01:17:11 +08:00
func ( new_data [ upload_field_name ] [ " filename " ] , new_data [ upload_field_name ] [ " content " ] , save )
2005-08-02 05:29:52 +08:00
def get_directory_name ( self ) :
2007-07-06 18:21:14 +08:00
return os . path . normpath ( force_unicode ( datetime . datetime . now ( ) . strftime ( smart_str ( self . upload_to ) ) ) )
2005-08-02 05:29:52 +08:00
def get_filename ( self , filename ) :
from django . utils . text import get_valid_filename
f = os . path . join ( self . get_directory_name ( ) , get_valid_filename ( os . path . basename ( filename ) ) )
return os . path . normpath ( f )
2005-10-12 12:14:21 +08:00
class FilePathField ( Field ) :
def __init__ ( self , verbose_name = None , name = None , path = ' ' , match = None , recursive = False , * * kwargs ) :
self . path , self . match , self . recursive = path , match , recursive
Field . __init__ ( self , verbose_name , name , * * kwargs )
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ curry ( oldforms . FilePathField , path = self . path , match = self . match , recursive = self . recursive ) ]
2005-10-12 12:14:21 +08:00
2005-08-02 05:29:52 +08:00
class FloatField ( Field ) :
empty_strings_allowed = False
def get_manipulator_field_objs ( self ) :
2007-05-21 09:29:58 +08:00
return [ oldforms . FloatField ]
def formfield ( self , * * kwargs ) :
defaults = { ' form_class ' : forms . FloatField }
defaults . update ( kwargs )
return super ( FloatField , self ) . formfield ( * * defaults )
2005-08-02 05:29:52 +08:00
class ImageField ( FileField ) :
2005-08-26 06:51:30 +08:00
def __init__ ( self , verbose_name = None , name = None , width_field = None , height_field = None , * * kwargs ) :
2005-08-02 05:29:52 +08:00
self . width_field , self . height_field = width_field , height_field
2005-08-26 06:51:30 +08:00
FileField . __init__ ( self , verbose_name , name , * * kwargs )
2005-08-02 05:29:52 +08:00
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . ImageUploadField , oldforms . HiddenField ]
2006-05-02 09:31:56 +08:00
def contribute_to_class ( self , cls , name ) :
super ( ImageField , self ) . contribute_to_class ( cls , name )
# Add get_BLAH_width and get_BLAH_height methods, but only if the
# image field doesn't have width and height cache fields.
if not self . width_field :
setattr ( cls , ' get_ %s _width ' % self . name , curry ( cls . _get_FIELD_width , field = self ) )
if not self . height_field :
setattr ( cls , ' get_ %s _height ' % self . name , curry ( cls . _get_FIELD_height , field = self ) )
2005-08-02 05:29:52 +08:00
2007-02-27 01:17:11 +08:00
def save_file ( self , new_data , new_object , original_object , change , rel , save = True ) :
FileField . save_file ( self , new_data , new_object , original_object , change , rel , save )
2005-08-02 05:29:52 +08:00
# If the image has height and/or width field(s) and they haven't
# changed, set the width and/or height field(s) back to their original
# values.
2007-02-27 01:17:11 +08:00
if change and ( self . width_field or self . height_field ) and save :
2005-08-02 05:29:52 +08:00
if self . width_field :
setattr ( new_object , self . width_field , getattr ( original_object , self . width_field ) )
if self . height_field :
setattr ( new_object , self . height_field , getattr ( original_object , self . height_field ) )
new_object . save ( )
class IntegerField ( Field ) :
empty_strings_allowed = False
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . IntegerField ]
2005-08-02 05:29:52 +08:00
2007-01-22 14:32:14 +08:00
def formfield ( self , * * kwargs ) :
2007-04-28 21:55:24 +08:00
defaults = { ' form_class ' : forms . IntegerField }
2007-01-22 14:32:14 +08:00
defaults . update ( kwargs )
2007-04-28 21:55:24 +08:00
return super ( IntegerField , self ) . formfield ( * * defaults )
2006-12-16 02:32:42 +08:00
2005-08-02 05:29:52 +08:00
class IPAddressField ( Field ) :
2007-06-26 20:59:49 +08:00
empty_strings_allowed = False
2005-08-02 05:29:52 +08:00
def __init__ ( self , * args , * * kwargs ) :
2007-08-05 13:14:46 +08:00
kwargs [ ' max_length ' ] = 15
2005-08-02 05:29:52 +08:00
Field . __init__ ( self , * args , * * kwargs )
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . IPAddressField ]
2006-05-02 09:31:56 +08:00
def validate ( self , field_data , all_data ) :
validators . isValidIPAddress4 ( field_data , None )
2005-08-02 05:29:52 +08:00
class NullBooleanField ( Field ) :
2007-06-23 22:16:00 +08:00
empty_strings_allowed = False
2005-08-02 05:29:52 +08:00
def __init__ ( self , * args , * * kwargs ) :
kwargs [ ' null ' ] = True
Field . __init__ ( self , * args , * * kwargs )
2007-03-13 08:35:47 +08:00
def to_python ( self , value ) :
if value in ( None , True , False ) : return value
if value in ( ' None ' ) : return None
if value in ( ' t ' , ' True ' , ' 1 ' ) : return True
if value in ( ' f ' , ' False ' , ' 0 ' ) : return False
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
raise validators . ValidationError , _ ( " This value must be either None, True or False. " )
2007-03-13 08:35:47 +08:00
2005-08-02 05:29:52 +08:00
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . NullBooleanField ]
2005-08-02 05:29:52 +08:00
class PhoneNumberField ( IntegerField ) :
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . PhoneNumberField ]
2006-05-02 09:31:56 +08:00
def validate ( self , field_data , all_data ) :
validators . isValidPhone ( field_data , all_data )
2005-08-02 05:29:52 +08:00
2007-02-21 13:59:46 +08:00
def formfield ( self , * * kwargs ) :
2007-04-08 19:21:00 +08:00
from django . contrib . localflavor . us . forms import USPhoneNumberField
2007-04-28 21:55:24 +08:00
defaults = { ' form_class ' : USPhoneNumberField }
2007-02-21 13:59:46 +08:00
defaults . update ( kwargs )
2007-04-28 21:55:24 +08:00
return super ( PhoneNumberField , self ) . formfield ( * * defaults )
2007-02-21 13:59:46 +08:00
2005-08-02 05:29:52 +08:00
class PositiveIntegerField ( IntegerField ) :
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . PositiveIntegerField ]
2005-08-02 05:29:52 +08:00
class PositiveSmallIntegerField ( IntegerField ) :
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . PositiveSmallIntegerField ]
2005-08-02 05:29:52 +08:00
class SlugField ( Field ) :
def __init__ ( self , * args , * * kwargs ) :
2007-08-05 13:14:46 +08:00
kwargs [ ' max_length ' ] = kwargs . get ( ' max_length ' , 50 )
2005-10-20 12:20:52 +08:00
kwargs . setdefault ( ' validator_list ' , [ ] ) . append ( validators . isSlug )
2005-08-02 05:29:52 +08:00
# Set db_index=True unless it's been set manually.
2007-04-26 21:30:48 +08:00
if ' db_index ' not in kwargs :
2005-08-02 05:29:52 +08:00
kwargs [ ' db_index ' ] = True
Field . __init__ ( self , * args , * * kwargs )
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . TextField ]
2005-08-02 05:29:52 +08:00
class SmallIntegerField ( IntegerField ) :
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . SmallIntegerField ]
2005-08-02 05:29:52 +08:00
class TextField ( Field ) :
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . LargeTextField ]
2005-08-02 05:29:52 +08:00
2007-01-22 14:32:14 +08:00
def formfield ( self , * * kwargs ) :
2007-04-28 21:55:24 +08:00
defaults = { ' widget ' : forms . Textarea }
2007-01-22 14:32:14 +08:00
defaults . update ( kwargs )
2007-04-28 21:55:24 +08:00
return super ( TextField , self ) . formfield ( * * defaults )
2007-01-11 07:34:37 +08:00
2005-08-02 05:29:52 +08:00
class TimeField ( Field ) :
empty_strings_allowed = False
2005-08-26 06:51:30 +08:00
def __init__ ( self , verbose_name = None , name = None , auto_now = False , auto_now_add = False , * * kwargs ) :
2006-05-02 09:31:56 +08:00
self . auto_now , self . auto_now_add = auto_now , auto_now_add
2005-08-02 05:29:52 +08:00
if auto_now or auto_now_add :
kwargs [ ' editable ' ] = False
2005-08-26 06:51:30 +08:00
Field . __init__ ( self , verbose_name , name , * * kwargs )
2005-08-02 05:29:52 +08:00
def get_db_prep_lookup ( self , lookup_type , value ) :
2007-06-23 22:16:00 +08:00
if settings . DATABASE_ENGINE == ' oracle ' :
# Oracle requires a date in order to parse.
def prep ( value ) :
if isinstance ( value , datetime . time ) :
value = datetime . datetime . combine ( datetime . date ( 1900 , 1 , 1 ) , value )
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
return smart_unicode ( value )
2007-06-23 22:16:00 +08:00
else :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
prep = smart_unicode
2005-08-02 05:29:52 +08:00
if lookup_type == ' range ' :
2007-06-23 22:16:00 +08:00
value = [ prep ( v ) for v in value ]
2005-08-02 05:29:52 +08:00
else :
2007-06-23 22:16:00 +08:00
value = prep ( value )
2005-08-02 05:29:52 +08:00
return Field . get_db_prep_lookup ( self , lookup_type , value )
2006-05-30 01:08:58 +08:00
def pre_save ( self , model_instance , add ) :
2005-08-10 11:50:46 +08:00
if self . auto_now or ( self . auto_now_add and add ) :
2006-05-30 01:08:58 +08:00
value = datetime . datetime . now ( ) . time ( )
setattr ( model_instance , self . attname , value )
return value
else :
return super ( TimeField , self ) . pre_save ( model_instance , add )
2005-08-02 05:29:52 +08:00
2005-08-10 11:12:37 +08:00
def get_db_prep_save ( self , value ) :
2005-08-02 05:29:52 +08:00
# Casts dates into string format for entry into database.
if value is not None :
2005-08-15 09:03:39 +08:00
# MySQL will throw a warning if microseconds are given, because it
# doesn't support microseconds.
2007-03-14 20:08:19 +08:00
if settings . DATABASE_ENGINE == ' mysql ' and hasattr ( value , ' microsecond ' ) :
2005-08-15 09:03:39 +08:00
value = value . replace ( microsecond = 0 )
2007-06-23 22:16:00 +08:00
if settings . DATABASE_ENGINE == ' oracle ' :
# cx_Oracle expects a datetime.datetime to persist into TIMESTAMP field.
if isinstance ( value , datetime . time ) :
value = datetime . datetime ( 1900 , 1 , 1 , value . hour , value . minute ,
value . second , value . microsecond )
elif isinstance ( value , basestring ) :
value = datetime . datetime ( * ( time . strptime ( value , ' % H: % M: % S ' ) [ : 6 ] ) )
else :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
value = smart_unicode ( value )
2005-08-10 11:12:37 +08:00
return Field . get_db_prep_save ( self , value )
2005-08-02 05:29:52 +08:00
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . TimeField ]
2005-08-02 05:29:52 +08:00
2005-11-26 05:20:09 +08:00
def flatten_data ( self , follow , obj = None ) :
val = self . _get_val_from_obj ( obj )
return { self . attname : ( val is not None and val . strftime ( " % H: % M: % S " ) or ' ' ) }
2007-01-22 14:32:14 +08:00
def formfield ( self , * * kwargs ) :
2007-04-28 21:55:24 +08:00
defaults = { ' form_class ' : forms . TimeField }
2007-01-22 14:32:14 +08:00
defaults . update ( kwargs )
2007-04-28 21:55:24 +08:00
return super ( TimeField , self ) . formfield ( * * defaults )
2006-12-16 02:32:42 +08:00
2007-01-09 04:28:31 +08:00
class URLField ( CharField ) :
2005-08-26 06:51:30 +08:00
def __init__ ( self , verbose_name = None , name = None , verify_exists = True , * * kwargs ) :
2007-08-05 13:14:46 +08:00
kwargs [ ' max_length ' ] = kwargs . get ( ' max_length ' , 200 )
2005-08-02 05:29:52 +08:00
if verify_exists :
kwargs . setdefault ( ' validator_list ' , [ ] ) . append ( validators . isExistingURL )
2006-12-16 02:32:42 +08:00
self . verify_exists = verify_exists
2007-01-09 04:28:31 +08:00
CharField . __init__ ( self , verbose_name , name , * * kwargs )
2005-08-02 05:29:52 +08:00
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . URLField ]
2005-08-02 05:29:52 +08:00
2007-01-11 07:34:37 +08:00
def get_internal_type ( self ) :
2007-01-09 04:28:31 +08:00
return " CharField "
2007-01-22 14:32:14 +08:00
def formfield ( self , * * kwargs ) :
2007-04-28 21:55:24 +08:00
defaults = { ' form_class ' : forms . URLField , ' verify_exists ' : self . verify_exists }
2007-01-22 14:32:14 +08:00
defaults . update ( kwargs )
2007-04-28 21:55:24 +08:00
return super ( URLField , self ) . formfield ( * * defaults )
2006-12-16 02:32:42 +08:00
2005-08-02 05:29:52 +08:00
class USStateField ( Field ) :
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . USStateField ]
2005-08-02 05:29:52 +08:00
2007-05-01 10:35:15 +08:00
def formfield ( self , * * kwargs ) :
from django . contrib . localflavor . us . forms import USStateSelect
defaults = { ' widget ' : USStateSelect }
defaults . update ( kwargs )
return super ( USStateField , self ) . formfield ( * * defaults )
2005-09-29 07:08:47 +08:00
class XMLField ( TextField ) :
2005-08-26 06:51:30 +08:00
def __init__ ( self , verbose_name = None , name = None , schema_path = None , * * kwargs ) :
2005-08-02 05:29:52 +08:00
self . schema_path = schema_path
2005-08-26 06:51:30 +08:00
Field . __init__ ( self , verbose_name , name , * * kwargs )
2005-08-02 05:29:52 +08:00
2005-09-29 07:08:47 +08:00
def get_internal_type ( self ) :
return " TextField "
2005-08-02 05:29:52 +08:00
def get_manipulator_field_objs ( self ) :
2006-12-16 02:00:50 +08:00
return [ curry ( oldforms . XMLLargeTextField , schema_path = self . schema_path ) ]
2005-08-02 05:29:52 +08:00
2006-05-02 09:31:56 +08:00
class OrderingField ( IntegerField ) :
empty_strings_allowed = False
def __init__ ( self , with_respect_to , * * kwargs ) :
self . wrt = with_respect_to
kwargs [ ' null ' ] = True
IntegerField . __init__ ( self , * * kwargs )
2005-11-26 05:20:09 +08:00
2006-05-02 09:31:56 +08:00
def get_internal_type ( self ) :
return " IntegerField "
2005-11-26 05:20:09 +08:00
2006-05-02 09:31:56 +08:00
def get_manipulator_fields ( self , opts , manipulator , change , name_prefix = ' ' , rel = False , follow = True ) :
2006-12-16 02:00:50 +08:00
return [ oldforms . HiddenField ( name_prefix + self . name ) ]