diff --git a/django/contrib/gis/tests/relatedapp/models.py b/django/contrib/gis/tests/relatedapp/models.py index 8484054e0d..ff4beb4647 100644 --- a/django/contrib/gis/tests/relatedapp/models.py +++ b/django/contrib/gis/tests/relatedapp/models.py @@ -1,4 +1,5 @@ from django.contrib.gis.db import models +from django.contrib.localflavor.us.models import USStateField class Location(models.Model): name = models.CharField(max_length=50) @@ -7,6 +8,6 @@ class Location(models.Model): class City(models.Model): name = models.CharField(max_length=50) - state = models.USStateField() + state = USStateField() location = models.ForeignKey(Location) objects = models.GeoManager() diff --git a/django/contrib/gis/utils/layermapping.py b/django/contrib/gis/utils/layermapping.py index 40d2e97278..ad0cd5b4d6 100644 --- a/django/contrib/gis/utils/layermapping.py +++ b/django/contrib/gis/utils/layermapping.py @@ -118,6 +118,7 @@ from django.contrib.gis.gdal.field import \ OFTDate, OFTDateTime, OFTInteger, OFTReal, OFTString, OFTTime from django.contrib.gis.models import GeometryColumns, SpatialRefSys from django.db import models, transaction +from django.contrib.localflavor.us.models import USStateField # LayerMapping exceptions. class LayerMapError(Exception): pass @@ -150,7 +151,7 @@ class LayerMapping(object): models.SlugField : OFTString, models.TextField : OFTString, models.URLField : OFTString, - models.USStateField : OFTString, + USStateField : OFTString, models.XMLField : OFTString, models.SmallIntegerField : (OFTInteger, OFTReal, OFTString), models.PositiveSmallIntegerField : (OFTInteger, OFTReal, OFTString), diff --git a/django/contrib/localflavor/us/models.py b/django/contrib/localflavor/us/models.py new file mode 100644 index 0000000000..5158da4e87 --- /dev/null +++ b/django/contrib/localflavor/us/models.py @@ -0,0 +1,35 @@ +from django.conf import settings +from django.db.models.fields import Field + +class USStateField(Field): + def get_internal_type(self): + return "USStateField" + + def db_type(self): + if settings.DATABASE_ENGINE == 'oracle': + return 'CHAR(2)' + else: + return 'varchar(2)' + + def formfield(self, **kwargs): + from django.contrib.localflavor.us.forms import USStateSelect + defaults = {'widget': USStateSelect} + defaults.update(kwargs) + return super(USStateField, self).formfield(**defaults) + +class PhoneNumberField(Field): + def get_internal_type(self): + return "PhoneNumberField" + + def db_type(self): + if settings.DATABASE_ENGINE == 'oracle': + return 'VARCHAR2(20)' + else: + return 'varchar(20)' + + def formfield(self, **kwargs): + from django.contrib.localflavor.us.forms import USPhoneNumberField + defaults = {'form_class': USPhoneNumberField} + defaults.update(kwargs) + return super(PhoneNumberField, self).formfield(**defaults) + diff --git a/django/db/backends/mysql/creation.py b/django/db/backends/mysql/creation.py index 96faaacb75..0611e01643 100644 --- a/django/db/backends/mysql/creation.py +++ b/django/db/backends/mysql/creation.py @@ -21,14 +21,12 @@ class DatabaseCreation(BaseDatabaseCreation): 'IPAddressField': 'char(15)', 'NullBooleanField': 'bool', 'OneToOneField': 'integer', - 'PhoneNumberField': 'varchar(20)', 'PositiveIntegerField': 'integer UNSIGNED', 'PositiveSmallIntegerField': 'smallint UNSIGNED', 'SlugField': 'varchar(%(max_length)s)', 'SmallIntegerField': 'smallint', 'TextField': 'longtext', 'TimeField': 'time', - 'USStateField': 'varchar(2)', } def sql_table_creation_suffix(self): diff --git a/django/db/backends/oracle/creation.py b/django/db/backends/oracle/creation.py index 99c1b11a37..648c42f3ea 100644 --- a/django/db/backends/oracle/creation.py +++ b/django/db/backends/oracle/creation.py @@ -30,7 +30,6 @@ class DatabaseCreation(BaseDatabaseCreation): 'IPAddressField': 'VARCHAR2(15)', 'NullBooleanField': 'NUMBER(1) CHECK ((%(qn_column)s IN (0,1)) OR (%(qn_column)s IS NULL))', 'OneToOneField': 'NUMBER(11)', - 'PhoneNumberField': 'VARCHAR2(20)', 'PositiveIntegerField': 'NUMBER(11) CHECK (%(qn_column)s >= 0)', 'PositiveSmallIntegerField': 'NUMBER(11) CHECK (%(qn_column)s >= 0)', 'SlugField': 'NVARCHAR2(50)', @@ -38,7 +37,6 @@ class DatabaseCreation(BaseDatabaseCreation): 'TextField': 'NCLOB', 'TimeField': 'TIMESTAMP', 'URLField': 'VARCHAR2(%(max_length)s)', - 'USStateField': 'CHAR(2)', } remember = {} diff --git a/django/db/backends/postgresql/creation.py b/django/db/backends/postgresql/creation.py index 3e537e345e..8f329feca4 100644 --- a/django/db/backends/postgresql/creation.py +++ b/django/db/backends/postgresql/creation.py @@ -21,14 +21,12 @@ class DatabaseCreation(BaseDatabaseCreation): 'IPAddressField': 'inet', 'NullBooleanField': 'boolean', 'OneToOneField': 'integer', - 'PhoneNumberField': 'varchar(20)', 'PositiveIntegerField': 'integer CHECK ("%(column)s" >= 0)', 'PositiveSmallIntegerField': 'smallint CHECK ("%(column)s" >= 0)', 'SlugField': 'varchar(%(max_length)s)', 'SmallIntegerField': 'smallint', 'TextField': 'text', 'TimeField': 'time', - 'USStateField': 'varchar(2)', } def sql_table_creation_suffix(self): diff --git a/django/db/backends/sqlite3/creation.py b/django/db/backends/sqlite3/creation.py index 8943854af4..e9e0a94634 100644 --- a/django/db/backends/sqlite3/creation.py +++ b/django/db/backends/sqlite3/creation.py @@ -22,14 +22,12 @@ class DatabaseCreation(BaseDatabaseCreation): 'IPAddressField': 'char(15)', 'NullBooleanField': 'bool', 'OneToOneField': 'integer', - 'PhoneNumberField': 'varchar(20)', 'PositiveIntegerField': 'integer unsigned', 'PositiveSmallIntegerField': 'smallint unsigned', 'SlugField': 'varchar(%(max_length)s)', 'SmallIntegerField': 'smallint', 'TextField': 'text', 'TimeField': 'time', - 'USStateField': 'varchar(2)', } def sql_for_pending_references(self, model, style, pending_references): diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 7e56542024..afa1c13238 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -741,16 +741,6 @@ class NullBooleanField(Field): defaults.update(kwargs) return super(NullBooleanField, self).formfield(**defaults) -class PhoneNumberField(Field): - def get_internal_type(self): - return "PhoneNumberField" - - def formfield(self, **kwargs): - from django.contrib.localflavor.us.forms import USPhoneNumberField - defaults = {'form_class': USPhoneNumberField} - defaults.update(kwargs) - return super(PhoneNumberField, self).formfield(**defaults) - class PositiveIntegerField(IntegerField): def get_internal_type(self): return "PositiveIntegerField" @@ -876,16 +866,6 @@ class URLField(CharField): defaults.update(kwargs) return super(URLField, self).formfield(**defaults) -class USStateField(Field): - def get_internal_type(self): - return "USStateField" - - def formfield(self, **kwargs): - from django.contrib.localflavor.us.forms import USStateSelect - defaults = {'widget': USStateSelect} - defaults.update(kwargs) - return super(USStateField, self).formfield(**defaults) - class XMLField(TextField): def __init__(self, verbose_name=None, name=None, schema_path=None, **kwargs): self.schema_path = schema_path diff --git a/docs/ref/contrib/localflavor.txt b/docs/ref/contrib/localflavor.txt index 5a3fed34c6..25b60de2d0 100644 --- a/docs/ref/contrib/localflavor.txt +++ b/docs/ref/contrib/localflavor.txt @@ -649,3 +649,8 @@ United States of America (``us``) A form ``Select`` widget that uses a list of U.S. states/territories as its choices. + +.. class:: us.models.USStateField + + A model field that forms represent as a ``forms.USStateField`` field and + stores the two-letter U.S. state abbreviation in the database. diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index f5c8f72356..5f656da66a 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -705,14 +705,6 @@ Like all ::class:`CharField` subclasses, :class:`URLField` takes the optional :attr:`~CharField.max_length`argument. If you don't specify :attr:`~CharField.max_length`, a default of 200 is used. -``USStateField`` ----------------- - -.. class:: USStateField([**options]) - -A two-letter U.S. state abbreviation. The admin represents this as an ```` (a single-line input). - ``XMLField`` ------------ diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt index 645d643a05..9418bf6004 100644 --- a/docs/topics/db/models.txt +++ b/docs/topics/db/models.txt @@ -625,13 +625,14 @@ model. For example, this model has a few custom methods:: + from django.contrib.localflavor.us.models import USStateField class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) birth_date = models.DateField() address = models.CharField(max_length=100) city = models.CharField(max_length=50) - state = models.USStateField() # Yes, this is America-centric... + state = USStateField() # Yes, this is America-centric... def baby_boomer_status(self): "Returns the person's baby-boomer status." diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt index fe1e053d50..80857aea9a 100644 --- a/docs/topics/forms/modelforms.txt +++ b/docs/topics/forms/modelforms.txt @@ -73,10 +73,6 @@ the full list of conversions: ``TimeField`` ``TimeField`` ``URLField`` ``URLField`` with ``verify_exists`` set to the model field's ``verify_exists`` - ``USStateField`` ``CharField`` with - ``widget=USStateSelect`` - (``USStateSelect`` is from - ``django.contrib.localflavor.us``) ``XMLField`` ``CharField`` with ``widget=Textarea`` =============================== ======================================== diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py index 252d46deac..a11972d431 100644 --- a/tests/modeltests/model_forms/models.py +++ b/tests/modeltests/model_forms/models.py @@ -82,8 +82,9 @@ class WriterProfile(models.Model): def __unicode__(self): return "%s is %s" % (self.writer, self.age) +from django.contrib.localflavor.us.models import PhoneNumberField class PhoneNumber(models.Model): - phone = models.PhoneNumberField() + phone = PhoneNumberField() description = models.CharField(max_length=20) def __unicode__(self): diff --git a/tests/regressiontests/serializers_regress/models.py b/tests/regressiontests/serializers_regress/models.py index d2c06234fb..e26b8df6c0 100644 --- a/tests/regressiontests/serializers_regress/models.py +++ b/tests/regressiontests/serializers_regress/models.py @@ -8,6 +8,7 @@ This class sets up a model for each model field type from django.db import models from django.contrib.contenttypes import generic from django.contrib.contenttypes.models import ContentType +from django.contrib.localflavor.us.models import USStateField, PhoneNumberField # The following classes are for testing basic data # marshalling, including NULL values. @@ -52,7 +53,7 @@ class NullBooleanData(models.Model): data = models.NullBooleanField(null=True) class PhoneData(models.Model): - data = models.PhoneNumberField(null=True) + data = PhoneNumberField(null=True) class PositiveIntegerData(models.Model): data = models.PositiveIntegerField(null=True) @@ -73,7 +74,7 @@ class TimeData(models.Model): data = models.TimeField(null=True) class USStateData(models.Model): - data = models.USStateField(null=True) + data = USStateField(null=True) class XMLData(models.Model): data = models.XMLField(null=True) @@ -188,7 +189,7 @@ class IPAddressPKData(models.Model): # data = models.NullBooleanField(primary_key=True) class PhonePKData(models.Model): - data = models.PhoneNumberField(primary_key=True) + data = PhoneNumberField(primary_key=True) class PositiveIntegerPKData(models.Model): data = models.PositiveIntegerField(primary_key=True) @@ -209,7 +210,7 @@ class SmallPKData(models.Model): # data = models.TimeField(primary_key=True) class USStatePKData(models.Model): - data = models.USStateField(primary_key=True) + data = USStateField(primary_key=True) # class XMLPKData(models.Model): # data = models.XMLField(primary_key=True)