Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Refactored meta.py -- created a django.core.meta package, with init.p…

…y and fields.py

git-svn-id: http://code.djangoproject.com/svn/django/trunk@378 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit e0c3dd3318f6f4895554521c6bf69676635b1937 1 parent 006e9e7
Adrian Holovaty authored August 01, 2005
4  django/core/management.py
@@ -264,7 +264,7 @@ def database_check(mod):
264 264
 
265 265
 def get_admin_index(mod):
266 266
     "Returns admin-index template snippet (in list form) for the given module."
267  
-    from django.core import meta
  267
+    from django.utils.text import capfirst
268 268
     output = []
269 269
     app_label = mod._MODELS[0]._meta.app_label
270 270
     output.append('{%% if perms.%s %%}' % app_label)
@@ -274,7 +274,7 @@ def get_admin_index(mod):
274 274
             output.append(MODULE_TEMPLATE % {
275 275
                 'app': app_label,
276 276
                 'mod': klass._meta.module_name,
277  
-                'name': meta.capfirst(klass._meta.verbose_name_plural),
  277
+                'name': capfirst(klass._meta.verbose_name_plural),
278 278
                 'addperm': klass._meta.get_add_permission(),
279 279
                 'changeperm': klass._meta.get_change_permission(),
280 280
             })
684  django/core/meta.py → django/core/meta/__init__.py
... ...
@@ -1,30 +1,20 @@
  1
+from django.conf import settings
1 2
 from django.core import formfields, validators
2 3
 from django.core import db
3 4
 from django.core.exceptions import ObjectDoesNotExist
4  
-from django.conf import settings
  5
+from django.core.meta.fields import *
  6
+from django.utils.functional import curry
  7
+from django.utils.text import capfirst
5 8
 import copy, datetime, os, re, sys, types
6 9
 
7  
-# The values to use for "blank" in SelectFields. Will be appended to the start of most "choices" lists.
8  
-BLANK_CHOICE_DASH = [("", "---------")]
9  
-BLANK_CHOICE_NONE = [("", "None")]
10  
-
11 10
 # Admin stages.
12 11
 ADD, CHANGE, BOTH = 1, 2, 3
13 12
 
14  
-# Values for Relation.edit_inline_type.
15  
-TABULAR, STACKED = 1, 2
16  
-
17  
-# Values for filter_interface.
18  
-HORIZONTAL, VERTICAL = 1, 2
19  
-
20  
-# Random entropy string used by "default" param.
21  
-NOT_PROVIDED = 'oijpwojefiojpanv'
22  
-
23 13
 # Size of each "chunk" for get_iterator calls.
24 14
 # Larger values are slightly faster at the expense of more storage space.
25 15
 GET_ITERATOR_CHUNK_SIZE = 100
26 16
 
27  
-# Prefix (in python path style) to location of models.
  17
+# Prefix (in Python path style) to location of models.
28 18
 MODEL_PREFIX = 'django.models'
29 19
 
30 20
 # Methods on models with the following prefix will be removed and
@@ -37,21 +27,10 @@
37 27
 
38 28
 LOOKUP_SEPARATOR = '__'
39 29
 
40  
-RECURSIVE_RELATIONSHIP_CONSTANT = 'self'
41  
-
42 30
 ####################
43 31
 # HELPER FUNCTIONS #
44 32
 ####################
45 33
 
46  
-# capitalizes first letter of string
47  
-capfirst = lambda x: x and x[0].upper() + x[1:]
48  
-
49  
-# prepares a value for use in a LIKE query
50  
-prep_for_like_query = lambda x: str(x).replace("%", "\%").replace("_", "\_")
51  
-
52  
-# returns the <ul> class for a given radio_admin value
53  
-get_ul_class = lambda x: 'radiolist%s' % ((x == HORIZONTAL) and ' inline' or '')
54  
-
55 34
 # Django currently supports two forms of ordering.
56 35
 # Form 1 (deprecated) example:
57 36
 #     order_by=(('pub_date', 'DESC'), ('headline', 'ASC'), (None, 'RANDOM'))
@@ -82,11 +61,6 @@ def orderlist2sql(order_list, prefix=''):
82 61
             output.append('%s%s ASC' % (prefix, f))
83 62
     return ', '.join(output)
84 63
 
85  
-def curry(*args, **kwargs):
86  
-    def _curried(*moreargs, **morekwargs):
87  
-        return args[0](*(args[1:]+moreargs), **dict(kwargs.items() + morekwargs.items()))
88  
-    return _curried
89  
-
90 64
 def get_module(app_label, module_name):
91 65
     return __import__('%s.%s.%s' % (MODEL_PREFIX, app_label, module_name), '', '', [''])
92 66
 
@@ -1529,16 +1503,6 @@ def manipulator_save(opts, klass, add, change, self, new_data):
1529 1503
             getattr(new_object, 'set_%s_order' % rel_opts.object_name.lower())(order)
1530 1504
     return new_object
1531 1505
 
1532  
-def manipulator_validator_unique(f, opts, self, field_data, all_data):
1533  
-    "Validates that the value is unique for this field."
1534  
-    try:
1535  
-        old_obj = opts.get_model_module().get_object(**{'%s__exact' % f.name: field_data})
1536  
-    except ObjectDoesNotExist:
1537  
-        return
1538  
-    if hasattr(self, 'original_object') and getattr(self.original_object, opts.pk.name) == getattr(old_obj, opts.pk.name):
1539  
-        return
1540  
-    raise validators.ValidationError, "%s with this %s already exists." % (capfirst(opts.verbose_name), f.verbose_name)
1541  
-
1542 1506
 def manipulator_validator_unique_together(field_name_list, opts, self, field_data, all_data):
1543 1507
     from django.utils.text import get_text_list
1544 1508
     field_list = [opts.get_field(field_name) for field_name in field_name_list]
@@ -1583,641 +1547,3 @@ def manipulator_validator_unique_for_date(from_field, date_field, opts, lookup_t
1583 1547
             format_string = (lookup_type == 'date') and '%B %d, %Y' or '%B %Y'
1584 1548
             raise validators.ValidationError, "Please enter a different %s. The one you entered is already being used for %s." % \
1585 1549
                 (from_field.verbose_name, date_val.strftime(format_string))
1586  
-
1587  
-def manipulator_valid_rel_key(f, self, field_data, all_data):
1588  
-    "Validates that the value is a valid foreign key"
1589  
-    mod = f.rel.to.get_model_module()
1590  
-    try:
1591  
-        mod.get_object(**{'id__iexact': field_data})
1592  
-    except ObjectDoesNotExist:
1593  
-        raise validators.ValidationError, "Please enter a valid %s." % f.verbose_name
1594  
-
1595  
-####################
1596  
-# FIELDS           #
1597  
-####################
1598  
-
1599  
-class Field(object):
1600  
-
1601  
-    # Designates whether empty strings fundamentally are allowed at the
1602  
-    # database level.
1603  
-    empty_strings_allowed = True
1604  
-
1605  
-    def __init__(self, name, verbose_name=None, primary_key=False,
1606  
-        maxlength=None, unique=False, blank=False, null=False, db_index=None,
1607  
-        core=False, rel=None, default=NOT_PROVIDED, editable=True,
1608  
-        prepopulate_from=None, unique_for_date=None, unique_for_month=None,
1609  
-        unique_for_year=None, validator_list=None, choices=None, radio_admin=None,
1610  
-        help_text=''):
1611  
-        self.name = name
1612  
-        self.verbose_name = verbose_name or name.replace('_', ' ')
1613  
-        self.primary_key = primary_key
1614  
-        self.maxlength, self.unique = maxlength, unique
1615  
-        self.blank, self.null = blank, null
1616  
-        self.core, self.rel, self.default = core, rel, default
1617  
-        self.editable = editable
1618  
-        self.validator_list = validator_list or []
1619  
-        self.prepopulate_from = prepopulate_from
1620  
-        self.unique_for_date, self.unique_for_month = unique_for_date, unique_for_month
1621  
-        self.unique_for_year = unique_for_year
1622  
-        self.choices = choices or []
1623  
-        self.radio_admin = radio_admin
1624  
-        self.help_text = help_text
1625  
-        if rel and isinstance(rel, ManyToMany):
1626  
-            self.help_text += ' Hold down "Control", or "Command" on a Mac, to select more than one.'
1627  
-
1628  
-        # Set db_index to True if the field has a relationship and doesn't explicitly set db_index.
1629  
-        if db_index is None:
1630  
-            if isinstance(rel, OneToOne) or isinstance(rel, ManyToOne):
1631  
-                self.db_index = True
1632  
-            else:
1633  
-                self.db_index = False
1634  
-        else:
1635  
-            self.db_index = db_index
1636  
-
1637  
-    def pre_save(self, obj, value, add):
1638  
-        """
1639  
-        Hook for altering the object obj based on the value of this field and
1640  
-        and on the add/change status.
1641  
-        """
1642  
-        pass
1643  
-
1644  
-    def get_db_prep_save(self, value, add):
1645  
-        "Returns field's value prepared for saving into a database."
1646  
-        return value
1647  
-
1648  
-    def get_db_prep_lookup(self, lookup_type, value):
1649  
-        "Returns field's value prepared for database lookup."
1650  
-        if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'ne', 'month', 'day'):
1651  
-            return [value]
1652  
-        elif lookup_type in ('range', 'in'):
1653  
-            return value
1654  
-        elif lookup_type == 'year':
1655  
-            return ['%s-01-01' % value, '%s-12-31' % value]
1656  
-        elif lookup_type in ('contains', 'icontains'):
1657  
-            return ["%%%s%%" % prep_for_like_query(value)]
1658  
-        elif lookup_type == 'iexact':
1659  
-            return [prep_for_like_query(value)]
1660  
-        elif lookup_type in ('startswith', 'istartswith'):
1661  
-            return ["%s%%" % prep_for_like_query(value)]
1662  
-        elif lookup_type in ('endswith', 'iendswith'):
1663  
-            return ["%%%s" % prep_for_like_query(value)]
1664  
-        elif lookup_type == 'isnull':
1665  
-            return []
1666  
-        raise TypeError, "Field has invalid lookup: %s" % lookup_type
1667  
-
1668  
-    def has_default(self):
1669  
-        "Returns a boolean of whether this field has a default value."
1670  
-        return self.default != NOT_PROVIDED
1671  
-
1672  
-    def get_default(self):
1673  
-        "Returns the default value for this field."
1674  
-        if self.default != NOT_PROVIDED:
1675  
-            if hasattr(self.default, '__get_value__'):
1676  
-                return self.default.__get_value__()
1677  
-            return self.default
1678  
-        if self.null:
1679  
-            return None
1680  
-        return ""
1681  
-
1682  
-    def get_manipulator_field_names(self, name_prefix):
1683  
-        """
1684  
-        Returns a list of field names that this object adds to the manipulator.
1685  
-        """
1686  
-        return [name_prefix + self.name]
1687  
-
1688  
-    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False):
1689  
-        """
1690  
-        Returns a list of formfields.FormField instances for this field. It
1691  
-        calculates the choices at runtime, not at compile time.
1692  
-
1693  
-        name_prefix is a prefix to prepend to the "field_name" argument.
1694  
-        rel is a boolean specifying whether this field is in a related context.
1695  
-        """
1696  
-        params = {'validator_list': self.validator_list[:]}
1697  
-        if self.maxlength and not self.choices: # Don't give SelectFields a maxlength parameter.
1698  
-            params['maxlength'] = self.maxlength
1699  
-        if isinstance(self.rel, ManyToOne):
1700  
-            if self.rel.raw_id_admin:
1701  
-                field_objs = self.get_manipulator_field_objs()
1702  
-                params['validator_list'].append(curry(manipulator_valid_rel_key, self, manipulator))
1703  
-            else:
1704  
-                if self.radio_admin:
1705  
-                    field_objs = [formfields.RadioSelectField]
1706  
-                    params['choices'] = self.get_choices(include_blank=self.blank, blank_choice=BLANK_CHOICE_NONE)
1707  
-                    params['ul_class'] = get_ul_class(self.radio_admin)
1708  
-                else:
1709  
-                    if self.null:
1710  
-                        field_objs = [formfields.NullSelectField]
1711  
-                    else:
1712  
-                        field_objs = [formfields.SelectField]
1713  
-                    params['choices'] = self.get_choices()
1714  
-        elif self.choices:
1715  
-            if self.radio_admin:
1716  
-                field_objs = [formfields.RadioSelectField]
1717  
-                params['choices'] = self.get_choices(include_blank=self.blank, blank_choice=BLANK_CHOICE_NONE)
1718  
-                params['ul_class'] = get_ul_class(self.radio_admin)
1719  
-            else:
1720  
-                field_objs = [formfields.SelectField]
1721  
-                params['choices'] = self.get_choices()
1722  
-        else:
1723  
-            field_objs = self.get_manipulator_field_objs()
1724  
-
1725  
-        # Add the "unique" validator(s).
1726  
-        for field_name_list in opts.unique_together:
1727  
-            if field_name_list[0] == self.name:
1728  
-                params['validator_list'].append(getattr(manipulator, 'isUnique%s' % '_'.join(field_name_list)))
1729  
-
1730  
-        # Add the "unique for..." validator(s).
1731  
-        if self.unique_for_date:
1732  
-            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_date)))
1733  
-        if self.unique_for_month:
1734  
-            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_month)))
1735  
-        if self.unique_for_year:
1736  
-            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_year)))
1737  
-        if self.unique:
1738  
-            params['validator_list'].append(curry(manipulator_validator_unique, self, opts, manipulator))
1739  
-
1740  
-        # Only add is_required=True if the field cannot be blank. Primary keys
1741  
-        # are a special case, and fields in a related context should set this
1742  
-        # as False, because they'll be caught by a separate validator --
1743  
-        # RequiredIfOtherFieldGiven.
1744  
-        params['is_required'] = not self.blank and not self.primary_key and not rel
1745  
-
1746  
-        # If this field is in a related context, check whether any other fields
1747  
-        # in the related object have core=True. If so, add a validator --
1748  
-        # RequiredIfOtherFieldsGiven -- to this FormField.
1749  
-        if rel and not self.blank and not isinstance(self, AutoField) and not isinstance(self, FileField):
1750  
-            # First, get the core fields, if any.
1751  
-            core_field_names = []
1752  
-            for f in opts.fields:
1753  
-                if f.core and f != self:
1754  
-                    core_field_names.extend(f.get_manipulator_field_names(name_prefix))
1755  
-            # Now, if there are any, add the validator to this FormField.
1756  
-            if core_field_names:
1757  
-                params['validator_list'].append(validators.RequiredIfOtherFieldsGiven(core_field_names, "This field is required."))
1758  
-
1759  
-        # BooleanFields (CheckboxFields) are a special case. They don't take
1760  
-        # is_required or validator_list.
1761  
-        if isinstance(self, BooleanField):
1762  
-            del params['validator_list'], params['is_required']
1763  
-
1764  
-        # Finally, add the field_names.
1765  
-        field_names = self.get_manipulator_field_names(name_prefix)
1766  
-        return [man(field_name=field_names[i], **params) for i, man in enumerate(field_objs)]
1767  
-
1768  
-    def get_manipulator_new_data(self, new_data, rel=False):
1769  
-        """
1770  
-        Given the full new_data dictionary (from the manipulator), returns this
1771  
-        field's data.
1772  
-        """
1773  
-        if rel:
1774  
-            return new_data.get(self.name, [self.get_default()])[0]
1775  
-        else:
1776  
-            val = new_data.get(self.name, self.get_default())
1777  
-            if not self.empty_strings_allowed and val == '' and self.null:
1778  
-                val = None
1779  
-            return val
1780  
-
1781  
-    def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH):
1782  
-        "Returns a list of tuples used as SelectField choices for this field."
1783  
-        first_choice = include_blank and blank_choice or []
1784  
-        if self.choices:
1785  
-            return first_choice + list(self.choices)
1786  
-        rel_obj = self.rel.to
1787  
-        return first_choice + [(getattr(x, rel_obj.pk.name), repr(x)) for x in rel_obj.get_model_module().get_list(**self.rel.limit_choices_to)]
1788  
-
1789  
-class AutoField(Field):
1790  
-    empty_strings_allowed = False
1791  
-    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False):
1792  
-        if not rel:
1793  
-            return [] # Don't add a FormField unless it's in a related context.
1794  
-        return Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel)
1795  
-
1796  
-    def get_manipulator_field_objs(self):
1797  
-        return [formfields.HiddenField]
1798  
-
1799  
-    def get_manipulator_new_data(self, new_data, rel=False):
1800  
-        if not rel:
1801  
-            return None
1802  
-        return Field.get_manipulator_new_data(self, new_data, rel)
1803  
-
1804  
-class BooleanField(Field):
1805  
-    def __init__(self, *args, **kwargs):
1806  
-        kwargs['blank'] = True
1807  
-        Field.__init__(self, *args, **kwargs)
1808  
-
1809  
-    def get_manipulator_field_objs(self):
1810  
-        return [formfields.CheckboxField]
1811  
-
1812  
-class CharField(Field):
1813  
-    def get_manipulator_field_objs(self):
1814  
-        return [formfields.TextField]
1815  
-
1816  
-class CommaSeparatedIntegerField(CharField):
1817  
-    def get_manipulator_field_objs(self):
1818  
-        return [formfields.CommaSeparatedIntegerField]
1819  
-
1820  
-class DateField(Field):
1821  
-    empty_strings_allowed = False
1822  
-    def __init__(self, name, verbose_name=None, auto_now=False, auto_now_add=False, **kwargs):
1823  
-        self.auto_now, self.auto_now_add = auto_now, auto_now_add
1824  
-        if auto_now or auto_now_add:
1825  
-            kwargs['editable'] = False
1826  
-        Field.__init__(self, name, verbose_name, **kwargs)
1827  
-
1828  
-    def get_db_prep_lookup(self, lookup_type, value):
1829  
-        if lookup_type == 'range':
1830  
-            value = [str(v) for v in value]
1831  
-        else:
1832  
-            value = str(value)
1833  
-        return Field.get_db_prep_lookup(self, lookup_type, value)
1834  
-
1835  
-    def pre_save(self, obj, value, add):
1836  
-        if self.auto_now or (self.auto_now_add and add):
1837  
-            setattr(obj, self.name, datetime.datetime.now())
1838  
-
1839  
-    def get_db_prep_save(self, value, add):
1840  
-        # Casts dates into string format for entry into database.
1841  
-        if value is not None:
1842  
-            value = value.strftime('%Y-%m-%d')
1843  
-        return Field.get_db_prep_save(self, value, add)
1844  
-
1845  
-    def get_manipulator_field_objs(self):
1846  
-        return [formfields.DateField]
1847  
-
1848  
-class DateTimeField(DateField):
1849  
-    def get_db_prep_save(self, value, add):
1850  
-        # Casts dates into string format for entry into database.
1851  
-        if value is not None:
1852  
-            value = value.strftime('%Y-%m-%d %H:%M:%S')
1853  
-        return Field.get_db_prep_save(self, value, add)
1854  
-
1855  
-    def get_manipulator_field_objs(self):
1856  
-        return [formfields.DateField, formfields.TimeField]
1857  
-
1858  
-    def get_manipulator_field_names(self, name_prefix):
1859  
-        return [name_prefix + self.name + '_date', name_prefix + self.name + '_time']
1860  
-
1861  
-    def get_manipulator_new_data(self, new_data, rel=False):
1862  
-        date_field, time_field = self.get_manipulator_field_names('')
1863  
-        if rel:
1864  
-            d = new_data.get(date_field, [None])[0]
1865  
-            t = new_data.get(time_field, [None])[0]
1866  
-        else:
1867  
-            d = new_data.get(date_field, None)
1868  
-            t = new_data.get(time_field, None)
1869  
-        if d is not None and t is not None:
1870  
-            return datetime.datetime.combine(d, t)
1871  
-        return self.get_default()
1872  
-
1873  
-class EmailField(Field):
1874  
-    def get_manipulator_field_objs(self):
1875  
-        return [formfields.EmailField]
1876  
-
1877  
-class FileField(Field):
1878  
-    def __init__(self, name, verbose_name=None, upload_to='', **kwargs):
1879  
-        self.upload_to = upload_to
1880  
-        Field.__init__(self, name, verbose_name, **kwargs)
1881  
-
1882  
-    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False):
1883  
-        field_list = Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel)
1884  
-
1885  
-        if not self.blank:
1886  
-            if rel:
1887  
-                # This validator makes sure FileFields work in a related context.
1888  
-                class RequiredFileField:
1889  
-                    def __init__(self, other_field_names, other_file_field_name):
1890  
-                        self.other_field_names = other_field_names
1891  
-                        self.other_file_field_name = other_file_field_name
1892  
-                        self.always_test = True
1893  
-                    def __call__(self, field_data, all_data):
1894  
-                        if not all_data.get(self.other_file_field_name, False):
1895  
-                            c = validators.RequiredIfOtherFieldsGiven(self.other_field_names, "This field is required.")
1896  
-                            c(field_data, all_data)
1897  
-                # First, get the core fields, if any.
1898  
-                core_field_names = []
1899  
-                for f in opts.fields:
1900  
-                    if f.core and f != self:
1901  
-                        core_field_names.extend(f.get_manipulator_field_names(name_prefix))
1902  
-                # Now, if there are any, add the validator to this FormField.
1903  
-                if core_field_names:
1904  
-                    field_list[0].validator_list.append(RequiredFileField(core_field_names, field_list[1].field_name))
1905  
-            else:
1906  
-                v = validators.RequiredIfOtherFieldNotGiven(field_list[1].field_name, "This field is required.")
1907  
-                v.always_test = True
1908  
-                field_list[0].validator_list.append(v)
1909  
-                field_list[0].is_required = field_list[1].is_required = False
1910  
-
1911  
-        # If the raw path is passed in, validate it's under the MEDIA_ROOT.
1912  
-        def isWithinMediaRoot(field_data, all_data):
1913  
-            f = os.path.abspath(os.path.join(settings.MEDIA_ROOT, field_data))
1914  
-            if not f.startswith(os.path.normpath(settings.MEDIA_ROOT)):
1915  
-                raise validators.ValidationError, "Enter a valid filename."
1916  
-        field_list[1].validator_list.append(isWithinMediaRoot)
1917  
-        return field_list
1918  
-
1919  
-    def get_manipulator_field_objs(self):
1920  
-        return [formfields.FileUploadField, formfields.HiddenField]
1921  
-
1922  
-    def get_manipulator_field_names(self, name_prefix):
1923  
-        return [name_prefix + self.name + '_file', name_prefix + self.name]
1924  
-
1925  
-    def save_file(self, new_data, new_object, original_object, change, rel):
1926  
-        upload_field_name = self.get_manipulator_field_names('')[0]
1927  
-        if new_data.get(upload_field_name, False):
1928  
-            if rel:
1929  
-                getattr(new_object, 'save_%s_file' % self.name)(new_data[upload_field_name][0]["filename"], new_data[upload_field_name][0]["content"])
1930  
-            else:
1931  
-                getattr(new_object, 'save_%s_file' % self.name)(new_data[upload_field_name]["filename"], new_data[upload_field_name]["content"])
1932  
-
1933  
-    def get_directory_name(self):
1934  
-        return os.path.normpath(datetime.datetime.now().strftime(self.upload_to))
1935  
-
1936  
-    def get_filename(self, filename):
1937  
-        from django.utils.text import get_valid_filename
1938  
-        f = os.path.join(self.get_directory_name(), get_valid_filename(os.path.basename(filename)))
1939  
-        return os.path.normpath(f)
1940  
-
1941  
-class FloatField(Field):
1942  
-    empty_strings_allowed = False
1943  
-    def __init__(self, name, verbose_name=None, max_digits=None, decimal_places=None, **kwargs):
1944  
-        self.max_digits, self.decimal_places = max_digits, decimal_places
1945  
-        Field.__init__(self, name, verbose_name, **kwargs)
1946  
-
1947  
-    def get_manipulator_field_objs(self):
1948  
-        return [curry(formfields.FloatField, max_digits=self.max_digits, decimal_places=self.decimal_places)]
1949  
-
1950  
-class ImageField(FileField):
1951  
-    def __init__(self, name, verbose_name=None, width_field=None, height_field=None, **kwargs):
1952  
-        self.width_field, self.height_field = width_field, height_field
1953  
-        FileField.__init__(self, name, verbose_name, **kwargs)
1954  
-
1955  
-    def get_manipulator_field_objs(self):
1956  
-        return [formfields.ImageUploadField, formfields.HiddenField]
1957  
-
1958  
-    def save_file(self, new_data, new_object, original_object, change, rel):
1959  
-        FileField.save_file(self, new_data, new_object, original_object, change, rel)
1960  
-        # If the image has height and/or width field(s) and they haven't
1961  
-        # changed, set the width and/or height field(s) back to their original
1962  
-        # values.
1963  
-        if change and (self.width_field or self.height_field):
1964  
-            if self.width_field:
1965  
-                setattr(new_object, self.width_field, getattr(original_object, self.width_field))
1966  
-            if self.height_field:
1967  
-                setattr(new_object, self.height_field, getattr(original_object, self.height_field))
1968  
-            new_object.save()
1969  
-
1970  
-class IntegerField(Field):
1971  
-    empty_strings_allowed = False
1972  
-    def get_manipulator_field_objs(self):
1973  
-        return [formfields.IntegerField]
1974  
-
1975  
-class IPAddressField(Field):
1976  
-    def __init__(self, *args, **kwargs):
1977  
-        kwargs['maxlength'] = 15
1978  
-        Field.__init__(self, *args, **kwargs)
1979  
-
1980  
-    def get_manipulator_field_objs(self):
1981  
-        return [formfields.IPAddressField]
1982  
-
1983  
-class NullBooleanField(Field):
1984  
-    def __init__(self, *args, **kwargs):
1985  
-        kwargs['null'] = True
1986  
-        Field.__init__(self, *args, **kwargs)
1987  
-
1988  
-    def get_manipulator_field_objs(self):
1989  
-        return [formfields.NullBooleanField]
1990  
-
1991  
-class PhoneNumberField(IntegerField):
1992  
-    def get_manipulator_field_objs(self):
1993  
-        return [formfields.PhoneNumberField]
1994  
-
1995  
-class PositiveIntegerField(IntegerField):
1996  
-    def get_manipulator_field_objs(self):
1997  
-        return [formfields.PositiveIntegerField]
1998  
-
1999  
-class PositiveSmallIntegerField(IntegerField):
2000  
-    def get_manipulator_field_objs(self):
2001  
-        return [formfields.PositiveSmallIntegerField]
2002  
-
2003  
-class SlugField(Field):
2004  
-    def __init__(self, *args, **kwargs):
2005  
-        kwargs['maxlength'] = 50
2006  
-        kwargs.setdefault('validator_list', []).append(validators.isAlphaNumeric)
2007  
-        # Set db_index=True unless it's been set manually.
2008  
-        if not kwargs.has_key('db_index'):
2009  
-            kwargs['db_index'] = True
2010  
-        Field.__init__(self, *args, **kwargs)
2011  
-
2012  
-    def get_manipulator_field_objs(self):
2013  
-        return [formfields.TextField]
2014  
-
2015  
-class SmallIntegerField(IntegerField):
2016  
-    def get_manipulator_field_objs(self):
2017  
-        return [formfields.SmallIntegerField]
2018  
-
2019  
-class TextField(Field):
2020  
-    def get_manipulator_field_objs(self):
2021  
-        return [formfields.LargeTextField]
2022  
-
2023  
-class TimeField(Field):
2024  
-    empty_strings_allowed = False
2025  
-    def __init__(self, name, verbose_name=None, auto_now=False, auto_now_add=False, **kwargs):
2026  
-        self.auto_now, self.auto_now_add  = auto_now, auto_now_add
2027  
-        if auto_now or auto_now_add:
2028  
-            kwargs['editable'] = False
2029  
-        Field.__init__(self, name, verbose_name, **kwargs)
2030  
-
2031  
-    def get_db_prep_lookup(self, lookup_type, value):
2032  
-        if lookup_type == 'range':
2033  
-            value = [str(v) for v in value]
2034  
-        else:
2035  
-            value = str(value)
2036  
-        return Field.get_db_prep_lookup(self, lookup_type, value)
2037  
-
2038  
-    def pre_save(self, obj, value, add):
2039  
-        if self.auto_now or (self.auto_now_add and add):
2040  
-            setattr(obj, self.name, datetime.datetime.now().time())
2041  
-
2042  
-    def get_db_prep_save(self, value, add):
2043  
-        # Casts dates into string format for entry into database.
2044  
-        if value is not None:
2045  
-            value = value.strftime('%H:%M:%S')
2046  
-        return Field.get_db_prep_save(self, value, add)
2047  
-
2048  
-    def get_manipulator_field_objs(self):
2049  
-        return [formfields.TimeField]
2050  
-
2051  
-class URLField(Field):
2052  
-    def __init__(self, name, verbose_name=None, verify_exists=True, **kwargs):
2053  
-        if verify_exists:
2054  
-            kwargs.setdefault('validator_list', []).append(validators.isExistingURL)
2055  
-        Field.__init__(self, name, verbose_name, **kwargs)
2056  
-
2057  
-    def get_manipulator_field_objs(self):
2058  
-        return [formfields.URLField]
2059  
-
2060  
-class USStateField(Field):
2061  
-    def get_manipulator_field_objs(self):
2062  
-        return [formfields.USStateField]
2063  
-
2064  
-class XMLField(Field):
2065  
-    def __init__(self, name, verbose_name=None, schema_path=None, **kwargs):
2066  
-        self.schema_path = schema_path
2067  
-        Field.__init__(self, name, verbose_name, **kwargs)
2068  
-
2069  
-    def get_manipulator_field_objs(self):
2070  
-        return [curry(formfields.XMLLargeTextField, schema_path=self.schema_path)]
2071  
-
2072  
-class ForeignKey(Field):
2073  
-    empty_strings_allowed = False
2074  
-    def __init__(self, to, to_field=None, rel_name=None, **kwargs):
2075  
-        try:
2076  
-            to_name = to._meta.object_name.lower()
2077  
-        except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT
2078  
-            assert to == 'self', "ForeignKey(%r) is invalid. First parameter to ForeignKey must be either a model or the string %r" % (to, RECURSIVE_RELATIONSHIP_CONSTANT)
2079  
-            kwargs['name'] = kwargs.get('name', '')
2080  
-            kwargs['verbose_name'] = kwargs.get('verbose_name', '')
2081  
-        else:
2082  
-            to_field = to_field or to._meta.pk.name
2083  
-            kwargs['name'] = kwargs.get('name', to_name + '_id')
2084  
-            kwargs['verbose_name'] = kwargs.get('verbose_name', to._meta.verbose_name)
2085  
-            rel_name = rel_name or to_name
2086  
-        kwargs['rel'] = ManyToOne(to, rel_name, to_field,
2087  
-            num_in_admin=kwargs.pop('num_in_admin', 0),
2088  
-            min_num_in_admin=kwargs.pop('min_num_in_admin', None),
2089  
-            max_num_in_admin=kwargs.pop('max_num_in_admin', None),
2090  
-            num_extra_on_change=kwargs.pop('num_extra_on_change', 1),
2091  
-            edit_inline=kwargs.pop('edit_inline', False),
2092  
-            edit_inline_type=kwargs.pop('edit_inline_type', STACKED),
2093  
-            related_name=kwargs.pop('related_name', None),
2094  
-            limit_choices_to=kwargs.pop('limit_choices_to', None),
2095  
-            lookup_overrides=kwargs.pop('lookup_overrides', None),
2096  
-            raw_id_admin=kwargs.pop('raw_id_admin', False))
2097  
-        Field.__init__(self, **kwargs)
2098  
-
2099  
-    def get_manipulator_field_objs(self):
2100  
-        return [formfields.IntegerField]
2101  
-
2102  
-class ManyToManyField(Field):
2103  
-    def __init__(self, to, rel_name=None, **kwargs):
2104  
-        kwargs['name'] = kwargs.get('name', to._meta.module_name)
2105  
-        kwargs['verbose_name'] = kwargs.get('verbose_name', to._meta.verbose_name_plural)
2106  
-        rel_name = rel_name or to._meta.object_name.lower()
2107  
-        kwargs['rel'] = ManyToMany(to, rel_name,
2108  
-            num_in_admin=kwargs.pop('num_in_admin', 0),
2109  
-            related_name=kwargs.pop('related_name', None),
2110  
-            filter_interface=kwargs.pop('filter_interface', None),
2111  
-            limit_choices_to=kwargs.pop('limit_choices_to', None))
2112  
-        Field.__init__(self, **kwargs)
2113  
-
2114  
-    def get_manipulator_field_objs(self):
2115  
-        choices = self.get_choices(include_blank=False)
2116  
-        return [curry(formfields.SelectMultipleField, size=min(max(len(choices), 5), 15), choices=choices)]
2117  
-
2118  
-    def get_m2m_db_table(self, original_opts):
2119  
-        "Returns the name of the many-to-many 'join' table."
2120  
-        return '%s_%s' % (original_opts.db_table, self.name)
2121  
-
2122  
-class OneToOneField(IntegerField):
2123  
-    def __init__(self, to, to_field=None, rel_name=None, **kwargs):
2124  
-        kwargs['name'] = kwargs.get('name', 'id')
2125  
-        kwargs['verbose_name'] = kwargs.get('verbose_name', 'ID')
2126  
-        to_field = to_field or to._meta.pk.name
2127  
-        rel_name = rel_name or to._meta.object_name.lower()
2128  
-        kwargs['rel'] = OneToOne(to, rel_name, to_field,
2129  
-            num_in_admin=kwargs.pop('num_in_admin', 0),
2130  
-            edit_inline=kwargs.pop('edit_inline', False),
2131  
-            edit_inline_type=kwargs.pop('edit_inline_type', STACKED),
2132  
-            related_name=kwargs.pop('related_name', None),
2133  
-            limit_choices_to=kwargs.pop('limit_choices_to', None),
2134  
-            lookup_overrides=kwargs.pop('lookup_overrides', None),
2135  
-            raw_id_admin=kwargs.pop('raw_id_admin', False))
2136  
-        kwargs['primary_key'] = True
2137  
-        IntegerField.__init__(self, **kwargs)
2138  
-
2139  
-####################
2140  
-# RELATIONSHIPS    #
2141  
-####################
2142  
-
2143  
-class ManyToOne:
2144  
-    def __init__(self, to, name, field_name, num_in_admin=0, min_num_in_admin=None,
2145  
-        max_num_in_admin=None, num_extra_on_change=1, edit_inline=False, edit_inline_type=STACKED,
2146  
-        related_name=None, limit_choices_to=None, lookup_overrides=None, raw_id_admin=False):
2147  
-        try:
2148  
-            self.to = to._meta
2149  
-        except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT
2150  
-            assert to == RECURSIVE_RELATIONSHIP_CONSTANT, "'to' must be either a model or the string '%s'" % RECURSIVE_RELATIONSHIP_CONSTANT
2151  
-            self.to = to
2152  
-        self.name, self.field_name = name, field_name
2153  
-        self.num_in_admin, self.edit_inline = num_in_admin, edit_inline
2154  
-        self.min_num_in_admin, self.max_num_in_admin = min_num_in_admin, max_num_in_admin
2155  
-        self.num_extra_on_change = num_extra_on_change
2156  
-        self.edit_inline_type, self.related_name = edit_inline_type, related_name
2157  
-        self.limit_choices_to = limit_choices_to or {}
2158  
-        self.lookup_overrides = lookup_overrides or {}
2159  
-        self.raw_id_admin = raw_id_admin
2160  
-
2161  
-    def get_cache_name(self):
2162  
-        return '_%s_cache' % self.name
2163  
-
2164  
-    def get_related_field(self):
2165  
-        "Returns the Field in the 'to' object to which this relationship is tied."
2166  
-        return self.to.get_field(self.field_name)
2167  
-
2168  
-class ManyToMany:
2169  
-    def __init__(self, to, name, num_in_admin=0, related_name=None,
2170  
-        filter_interface=None, limit_choices_to=None):
2171  
-        self.to, self.name = to._meta, name
2172  
-        self.num_in_admin = num_in_admin
2173  
-        self.related_name = related_name
2174  
-        self.filter_interface = filter_interface
2175  
-        self.limit_choices_to = limit_choices_to or {}
2176  
-        self.edit_inline = False
2177  
-
2178  
-class OneToOne(ManyToOne):
2179  
-    def __init__(self, to, name, field_name, num_in_admin=0, edit_inline=False,
2180  
-        edit_inline_type=STACKED, related_name=None, limit_choices_to=None, lookup_overrides=None,
2181  
-        raw_id_admin=False):
2182  
-        self.to, self.name, self.field_name = to._meta, name, field_name
2183  
-        self.num_in_admin, self.edit_inline = num_in_admin, edit_inline
2184  
-        self.edit_inline_type, self.related_name = edit_inline_type, related_name
2185  
-        self.limit_choices_to = limit_choices_to or {}
2186  
-        self.lookup_overrides = lookup_overrides or {}
2187  
-        self.raw_id_admin = raw_id_admin
2188  
-
2189  
-class Admin:
2190  
-    def __init__(self, fields=None, js=None, list_display=None, list_filter=None, date_hierarchy=None,
2191  
-        save_as=False, ordering=None, search_fields=None, save_on_top=False):
2192  
-        self.fields = fields
2193  
-        self.js = js or []
2194  
-        self.list_display = list_display or ['__repr__']
2195  
-        self.list_filter = list_filter or []
2196  
-        self.date_hierarchy = date_hierarchy
2197  
-        self.save_as, self.ordering = save_as, ordering
2198  
-        self.search_fields = search_fields or []
2199  
-        self.save_on_top = save_on_top
2200  
-
2201  
-    def get_field_objs(self, opts):
2202  
-        """
2203  
-        Returns self.fields, except with fields as Field objects instead of
2204  
-        field names. If self.fields is None, defaults to putting every
2205  
-        non-AutoField field with editable=True in a single fieldset.
2206  
-        """
2207  
-        if self.fields is None:
2208  
-            field_struct = ((None, {'fields': [f.name for f in opts.fields + opts.many_to_many if f.editable and not isinstance(f, AutoField)]}),)
2209  
-        else:
2210  
-            field_struct = self.fields
2211  
-        new_fieldset_list = []
2212  
-        for fieldset in field_struct:
2213  
-            new_fieldset = [fieldset[0], {}]
2214  
-            new_fieldset[1].update(fieldset[1])
2215  
-            admin_fields = []
2216  
-            for field_name_or_list in fieldset[1]['fields']:
2217  
-                if isinstance(field_name_or_list, basestring):
2218  
-                    admin_fields.append([opts.get_field(field_name_or_list)])
2219  
-                else:
2220  
-                    admin_fields.append([opts.get_field(field_name) for field_name in field_name_or_list])
2221  
-            new_fieldset[1]['fields'] = admin_fields
2222  
-            new_fieldset_list.append(new_fieldset)
2223  
-        return new_fieldset_list
667  django/core/meta/fields.py
... ...
@@ -0,0 +1,667 @@
  1
+from django.conf import settings
  2
+from django.core import formfields, validators
  3
+from django.core.exceptions import ObjectDoesNotExist
  4
+from django.utils.functional import curry
  5
+from django.utils.text import capfirst
  6
+import datetime, os
  7
+
  8
+# Random entropy string used by "default" param.
  9
+NOT_PROVIDED = 'oijpwojefiojpanv'
  10
+
  11
+# Values for filter_interface.
  12
+HORIZONTAL, VERTICAL = 1, 2
  13
+
  14
+# The values to use for "blank" in SelectFields. Will be appended to the start of most "choices" lists.
  15
+BLANK_CHOICE_DASH = [("", "---------")]
  16
+BLANK_CHOICE_NONE = [("", "None")]
  17
+
  18
+# Values for Relation.edit_inline_type.
  19
+TABULAR, STACKED = 1, 2
  20
+
  21
+RECURSIVE_RELATIONSHIP_CONSTANT = 'self'
  22
+
  23
+# prepares a value for use in a LIKE query
  24
+prep_for_like_query = lambda x: str(x).replace("%", "\%").replace("_", "\_")
  25
+
  26
+# returns the <ul> class for a given radio_admin value
  27
+get_ul_class = lambda x: 'radiolist%s' % ((x == HORIZONTAL) and ' inline' or '')
  28
+
  29
+def manipulator_valid_rel_key(f, self, field_data, all_data):
  30
+    "Validates that the value is a valid foreign key"
  31
+    mod = f.rel.to.get_model_module()
  32
+    try:
  33
+        mod.get_object(**{'id__iexact': field_data})
  34
+    except ObjectDoesNotExist:
  35
+        raise validators.ValidationError, "Please enter a valid %s." % f.verbose_name
  36
+
  37
+def manipulator_validator_unique(f, opts, self, field_data, all_data):
  38
+    "Validates that the value is unique for this field."
  39
+    try:
  40
+        old_obj = opts.get_model_module().get_object(**{'%s__exact' % f.name: field_data})
  41
+    except ObjectDoesNotExist:
  42
+        return
  43
+    if hasattr(self, 'original_object') and getattr(self.original_object, opts.pk.name) == getattr(old_obj, opts.pk.name):
  44
+        return
  45
+    raise validators.ValidationError, "%s with this %s already exists." % (capfirst(opts.verbose_name), f.verbose_name)
  46
+
  47
+class Field(object):
  48
+
  49
+    # Designates whether empty strings fundamentally are allowed at the
  50
+    # database level.
  51
+    empty_strings_allowed = True
  52
+
  53
+    def __init__(self, name, verbose_name=None, primary_key=False,
  54
+        maxlength=None, unique=False, blank=False, null=False, db_index=None,
  55
+        core=False, rel=None, default=NOT_PROVIDED, editable=True,
  56
+        prepopulate_from=None, unique_for_date=None, unique_for_month=None,
  57
+        unique_for_year=None, validator_list=None, choices=None, radio_admin=None,
  58
+        help_text=''):
  59
+        self.name = name
  60
+        self.verbose_name = verbose_name or name.replace('_', ' ')
  61
+        self.primary_key = primary_key
  62
+        self.maxlength, self.unique = maxlength, unique
  63
+        self.blank, self.null = blank, null
  64
+        self.core, self.rel, self.default = core, rel, default
  65
+        self.editable = editable
  66
+        self.validator_list = validator_list or []
  67
+        self.prepopulate_from = prepopulate_from
  68
+        self.unique_for_date, self.unique_for_month = unique_for_date, unique_for_month
  69
+        self.unique_for_year = unique_for_year
  70
+        self.choices = choices or []
  71
+        self.radio_admin = radio_admin
  72
+        self.help_text = help_text
  73
+        if rel and isinstance(rel, ManyToMany):
  74
+            self.help_text += ' Hold down "Control", or "Command" on a Mac, to select more than one.'
  75
+
  76
+        # Set db_index to True if the field has a relationship and doesn't explicitly set db_index.
  77
+        if db_index is None:
  78
+            if isinstance(rel, OneToOne) or isinstance(rel, ManyToOne):
  79
+                self.db_index = True
  80
+            else:
  81
+                self.db_index = False
  82
+        else:
  83
+            self.db_index = db_index
  84
+
  85
+    def pre_save(self, obj, value, add):
  86
+        """
  87
+        Hook for altering the object obj based on the value of this field and
  88
+        and on the add/change status.
  89
+        """
  90
+        pass
  91
+
  92
+    def get_db_prep_save(self, value, add):
  93
+        "Returns field's value prepared for saving into a database."
  94
+        return value
  95
+
  96
+    def get_db_prep_lookup(self, lookup_type, value):
  97
+        "Returns field's value prepared for database lookup."
  98
+        if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'ne', 'month', 'day'):
  99
+            return [value]
  100
+        elif lookup_type in ('range', 'in'):
  101
+            return value
  102
+        elif lookup_type == 'year':
  103
+            return ['%s-01-01' % value, '%s-12-31' % value]
  104
+        elif lookup_type in ('contains', 'icontains'):
  105
+            return ["%%%s%%" % prep_for_like_query(value)]
  106
+        elif lookup_type == 'iexact':
  107
+            return [prep_for_like_query(value)]
  108
+        elif lookup_type in ('startswith', 'istartswith'):
  109
+            return ["%s%%" % prep_for_like_query(value)]
  110
+        elif lookup_type in ('endswith', 'iendswith'):
  111
+            return ["%%%s" % prep_for_like_query(value)]
  112
+        elif lookup_type == 'isnull':
  113
+            return []
  114
+        raise TypeError, "Field has invalid lookup: %s" % lookup_type
  115
+
  116
+    def has_default(self):
  117
+        "Returns a boolean of whether this field has a default value."
  118
+        return self.default != NOT_PROVIDED
  119
+
  120
+    def get_default(self):
  121
+        "Returns the default value for this field."
  122
+        if self.default != NOT_PROVIDED:
  123
+            if hasattr(self.default, '__get_value__'):
  124
+                return self.default.__get_value__()
  125
+            return self.default
  126
+        if self.null:
  127
+            return None
  128
+        return ""
  129
+
  130
+    def get_manipulator_field_names(self, name_prefix):
  131
+        """
  132
+        Returns a list of field names that this object adds to the manipulator.
  133
+        """
  134
+        return [name_prefix + self.name]
  135
+
  136
+    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False):
  137
+        """
  138
+        Returns a list of formfields.FormField instances for this field. It
  139
+        calculates the choices at runtime, not at compile time.
  140
+
  141
+        name_prefix is a prefix to prepend to the "field_name" argument.
  142
+        rel is a boolean specifying whether this field is in a related context.
  143
+        """
  144
+        params = {'validator_list': self.validator_list[:]}
  145
+        if self.maxlength and not self.choices: # Don't give SelectFields a maxlength parameter.
  146
+            params['maxlength'] = self.maxlength
  147
+        if isinstance(self.rel, ManyToOne):
  148
+            if self.rel.raw_id_admin:
  149
+                field_objs = self.get_manipulator_field_objs()
  150
+                params['validator_list'].append(curry(manipulator_valid_rel_key, self, manipulator))
  151
+            else:
  152
+                if self.radio_admin:
  153
+                    field_objs = [formfields.RadioSelectField]
  154
+                    params['choices'] = self.get_choices(include_blank=self.blank, blank_choice=BLANK_CHOICE_NONE)
  155
+                    params['ul_class'] = get_ul_class(self.radio_admin)
  156
+                else:
  157
+                    if self.null:
  158
+                        field_objs = [formfields.NullSelectField]
  159
+                    else:
  160
+                        field_objs = [formfields.SelectField]
  161
+                    params['choices'] = self.get_choices()
  162
+        elif self.choices:
  163
+            if self.radio_admin:
  164
+                field_objs = [formfields.RadioSelectField]
  165
+                params['choices'] = self.get_choices(include_blank=self.blank, blank_choice=BLANK_CHOICE_NONE)
  166
+                params['ul_class'] = get_ul_class(self.radio_admin)
  167
+            else:
  168
+                field_objs = [formfields.SelectField]
  169
+                params['choices'] = self.get_choices()
  170
+        else:
  171
+            field_objs = self.get_manipulator_field_objs()
  172
+
  173
+        # Add the "unique" validator(s).
  174
+        for field_name_list in opts.unique_together:
  175
+            if field_name_list[0] == self.name:
  176
+                params['validator_list'].append(getattr(manipulator, 'isUnique%s' % '_'.join(field_name_list)))
  177
+
  178
+        # Add the "unique for..." validator(s).
  179
+        if self.unique_for_date:
  180
+            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_date)))
  181
+        if self.unique_for_month:
  182
+            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_month)))
  183
+        if self.unique_for_year:
  184
+            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_year)))
  185
+        if self.unique:
  186
+            params['validator_list'].append(curry(manipulator_validator_unique, self, opts, manipulator))
  187
+
  188
+        # Only add is_required=True if the field cannot be blank. Primary keys
  189
+        # are a special case, and fields in a related context should set this
  190
+        # as False, because they'll be caught by a separate validator --
  191
+        # RequiredIfOtherFieldGiven.
  192
+        params['is_required'] = not self.blank and not self.primary_key and not rel
  193
+
  194
+        # If this field is in a related context, check whether any other fields
  195
+        # in the related object have core=True. If so, add a validator --
  196
+        # RequiredIfOtherFieldsGiven -- to this FormField.
  197
+        if rel and not self.blank and not isinstance(self, AutoField) and not isinstance(self, FileField):
  198
+            # First, get the core fields, if any.
  199
+            core_field_names = []
  200
+            for f in opts.fields:
  201
+                if f.core and f != self:
  202
+                    core_field_names.extend(f.get_manipulator_field_names(name_prefix))
  203
+            # Now, if there are any, add the validator to this FormField.
  204
+            if core_field_names:
  205
+                params['validator_list'].append(validators.RequiredIfOtherFieldsGiven(core_field_names, "This field is required."))
  206
+
  207
+        # BooleanFields (CheckboxFields) are a special case. They don't take
  208
+        # is_required or validator_list.
  209
+        if isinstance(self, BooleanField):
  210
+            del params['validator_list'], params['is_required']
  211
+
  212
+        # Finally, add the field_names.
  213
+        field_names = self.get_manipulator_field_names(name_prefix)
  214
+        return [man(field_name=field_names[i], **params) for i, man in enumerate(field_objs)]
  215
+
  216
+    def get_manipulator_new_data(self, new_data, rel=False):
  217
+        """
  218
+        Given the full new_data dictionary (from the manipulator), returns this
  219
+        field's data.
  220
+        """
  221
+        if rel:
  222
+            return new_data.get(self.name, [self.get_default()])[0]
  223
+        else:
  224
+            val = new_data.get(self.name, self.get_default())
  225
+            if not self.empty_strings_allowed and val == '' and self.null:
  226
+                val = None
  227
+            return val
  228
+
  229
+    def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH):
  230
+        "Returns a list of tuples used as SelectField choices for this field."
  231
+        first_choice = include_blank and blank_choice or []
  232
+        if self.choices:
  233
+            return first_choice + list(self.choices)
  234
+        rel_obj = self.rel.to
  235
+        return first_choice + [(getattr(x, rel_obj.pk.name), repr(x)) for x in rel_obj.get_model_module().get_list(**self.rel.limit_choices_to)]
  236
+
  237
+class AutoField(Field):
  238
+    empty_strings_allowed = False
  239
+    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False):
  240
+        if not rel:
  241
+            return [] # Don't add a FormField unless it's in a related context.
  242
+        return Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel)
  243
+
  244
+    def get_manipulator_field_objs(self):
  245
+        return [formfields.HiddenField]
  246
+
  247
+    def get_manipulator_new_data(self, new_data, rel=False):
  248
+        if not rel:
  249
+            return None
  250
+        return Field.get_manipulator_new_data(self, new_data, rel)
  251
+
  252
+class BooleanField(Field):
  253
+    def __init__(self, *args, **kwargs):
  254
+        kwargs['blank'] = True
  255
+        Field.__init__(self, *args, **kwargs)
  256
+
  257
+    def get_manipulator_field_objs(self):
  258
+        return [formfields.CheckboxField]
  259
+
  260
+class CharField(Field):
  261
+    def get_manipulator_field_objs(self):
  262
+        return [formfields.TextField]
  263
+
  264
+class CommaSeparatedIntegerField(CharField):
  265
+    def get_manipulator_field_objs(self):
  266
+        return [formfields.CommaSeparatedIntegerField]
  267
+
  268
+class DateField(Field):
  269
+    empty_strings_allowed = False
  270
+    def __init__(self, name, verbose_name=None, auto_now=False, auto_now_add=False, **kwargs):
  271
+        self.auto_now, self.auto_now_add = auto_now, auto_now_add
  272
+        if auto_now or auto_now_add:
  273
+            kwargs['editable'] = False
  274
+        Field.__init__(self, name, verbose_name, **kwargs)
  275
+
  276
+    def get_db_prep_lookup(self, lookup_type, value):
  277
+        if lookup_type == 'range':
  278
+            value = [str(v) for v in value]
  279
+        else:
  280
+            value = str(value)
  281
+        return Field.get_db_prep_lookup(self, lookup_type, value)
  282
+
  283
+    def pre_save(self, obj, value, add):
  284
+        if self.auto_now or (self.auto_now_add and add):
  285
+            setattr(obj, self.name, datetime.datetime.now())
  286
+
  287
+    def get_db_prep_save(self, value, add):
  288
+        # Casts dates into string format for entry into database.
  289
+        if value is not None:
  290
+            value = value.strftime('%Y-%m-%d')
  291
+        return Field.get_db_prep_save(self, value, add)
  292
+
  293
+    def get_manipulator_field_objs(self):
  294
+        return [formfields.DateField]
  295
+
  296
+class DateTimeField(DateField):
  297
+    def get_db_prep_save(self, value, add):
  298
+        # Casts dates into string format for entry into database.
  299
+        if value is not None:
  300
+            value = value.strftime('%Y-%m-%d %H:%M:%S')
  301
+        return Field.get_db_prep_save(self, value, add)
  302
+
  303
+    def get_manipulator_field_objs(self):
  304
+        return [formfields.DateField, formfields.TimeField]
  305
+
  306
+    def get_manipulator_field_names(self, name_prefix):
  307
+        return [name_prefix + self.name + '_date', name_prefix + self.name + '_time']
  308
+
  309
+    def get_manipulator_new_data(self, new_data, rel=False):
  310
+        date_field, time_field = self.get_manipulator_field_names('')
  311
+        if rel:
  312
+            d = new_data.get(date_field, [None])[0]
  313
+            t = new_data.get(time_field, [None])[0]
  314
+        else:
  315
+            d = new_data.get(date_field, None)
  316
+            t = new_data.get(time_field, None)
  317
+        if d is not None and t is not None:
  318
+            return datetime.datetime.combine(d, t)
  319
+        return self.get_default()
  320
+
  321
+class EmailField(Field):
  322
+    def get_manipulator_field_objs(self):
  323
+        return [formfields.EmailField]
  324
+
  325
+class FileField(Field):
  326
+    def __init__(self, name, verbose_name=None, upload_to='', **kwargs):
  327
+        self.upload_to = upload_to
  328
+        Field.__init__(self, name, verbose_name, **kwargs)
  329
+
  330
+    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False):
  331
+        field_list = Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel)
  332
+
  333
+        if not self.blank:
  334
+            if rel:
  335
+                # This validator makes sure FileFields work in a related context.
  336
+                class RequiredFileField:
  337
+                    def __init__(self, other_field_names, other_file_field_name):
  338
+                        self.other_field_names = other_field_names
  339
+                        self.other_file_field_name = other_file_field_name
  340
+                        self.always_test = True
  341
+                    def __call__(self, field_data, all_data):
  342