Removed IPAddressField per deprecation timeline; refs #20439.

This commit is contained in:
Tim Graham 2015-01-17 20:42:41 -05:00
parent 5008a4db44
commit 33457cd3b0
25 changed files with 117 additions and 161 deletions

View File

@ -1894,13 +1894,13 @@ class BigIntegerField(IntegerField):
class IPAddressField(Field):
empty_strings_allowed = False
description = _("IPv4 address")
system_check_deprecated_details = {
system_check_removed_details = {
'msg': (
'IPAddressField has been deprecated. Support for it (except in '
'historical migrations) will be removed in Django 1.9.'
'IPAddressField has been removed except for support in '
'historical migrations.'
),
'hint': 'Use GenericIPAddressField instead.',
'id': 'fields.W900',
'id': 'fields.E900',
}
def __init__(self, *args, **kwargs):
@ -1921,11 +1921,6 @@ class IPAddressField(Field):
def get_internal_type(self):
return "IPAddressField"
def formfield(self, **kwargs):
defaults = {'form_class': forms.IPAddressField}
defaults.update(kwargs)
return super(IPAddressField, self).formfield(**defaults)
class GenericIPAddressField(Field):
empty_strings_allowed = False

View File

@ -27,7 +27,7 @@ from django.utils import formats
from django.utils.encoding import smart_text, force_str, force_text
from django.utils.ipv6 import clean_ipv6_address
from django.utils.dateparse import parse_duration
from django.utils.deprecation import RemovedInDjango19Warning, RemovedInDjango20Warning, RenameMethodsBase
from django.utils.deprecation import RemovedInDjango20Warning, RenameMethodsBase
from django.utils.duration import duration_string
from django.utils import six
from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit
@ -43,7 +43,7 @@ __all__ = (
'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField',
'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField',
'ComboField', 'MultiValueField', 'FloatField', 'DecimalField',
'SplitDateTimeField', 'IPAddressField', 'GenericIPAddressField', 'FilePathField',
'SplitDateTimeField', 'GenericIPAddressField', 'FilePathField',
'SlugField', 'TypedChoiceField', 'TypedMultipleChoiceField', 'UUIDField',
)
@ -1206,20 +1206,6 @@ class SplitDateTimeField(MultiValueField):
return None
class IPAddressField(CharField):
default_validators = [validators.validate_ipv4_address]
def __init__(self, *args, **kwargs):
warnings.warn("IPAddressField has been deprecated. Use GenericIPAddressField instead.",
RemovedInDjango19Warning)
super(IPAddressField, self).__init__(*args, **kwargs)
def to_python(self, value):
if value in self.empty_values:
return ''
return value.strip()
class GenericIPAddressField(CharField):
def __init__(self, protocol='both', unpack_ipv4=False, *args, **kwargs):
self.unpack_ipv4 = unpack_ipv4

View File

@ -95,8 +95,11 @@ Fields
* **fields.E160**: The options ``auto_now``, ``auto_now_add``, and ``default``
are mutually exclusive. Only one of these options may be present.
* **fields.W161**: Fixed default value provided.
* **fields.E900**: ``IPAddressField`` has been removed except for support in
historical migrations.
* **fields.W900**: ``IPAddressField`` has been deprecated. Support for it
(except in historical migrations) will be removed in Django 1.9.
(except in historical migrations) will be removed in Django 1.9. *This check
appeared in Django 1.7 and 1.8*.
File Fields
~~~~~~~~~~~

View File

@ -719,22 +719,6 @@ For each field, we describe the default widget used if you don't specify
These control the range of values permitted in the field.
``IPAddressField``
~~~~~~~~~~~~~~~~~~
.. class:: IPAddressField(**kwargs)
.. deprecated:: 1.7
This field has been deprecated in favor of
:class:`~django.forms.GenericIPAddressField`.
* Default widget: :class:`TextInput`
* Empty value: ``''`` (an empty string)
* Normalizes to: A Unicode object.
* Validates that the given value is a valid IPv4 address, using a regular
expression.
* Error message keys: ``required``, ``invalid``
``GenericIPAddressField``
~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -892,18 +892,6 @@ An integer. Values from ``-2147483648`` to ``2147483647`` are safe in all
databases supported by Django. The default form widget for this field is a
:class:`~django.forms.TextInput`.
``IPAddressField``
------------------
.. class:: IPAddressField([**options])
.. deprecated:: 1.7
This field has been deprecated in favor of
:class:`~django.db.models.GenericIPAddressField`.
An IP address, in string format (e.g. "192.0.2.30"). The default form widget
for this field is a :class:`~django.forms.TextInput`.
``GenericIPAddressField``
-------------------------

View File

@ -96,7 +96,7 @@ field classes did not correctly convert their arguments:
* :class:`~django.db.models.FilePathField`
* :class:`~django.db.models.GenericIPAddressField`
* :class:`~django.db.models.IPAddressField`
* ``IPAddressField``
These three fields have been updated to convert their arguments to the
correct types before querying.

View File

@ -95,7 +95,7 @@ field classes did not correctly convert their arguments:
* :class:`~django.db.models.FilePathField`
* :class:`~django.db.models.GenericIPAddressField`
* :class:`~django.db.models.IPAddressField`
* ``IPAddressField``
These three fields have been updated to convert their arguments to the
correct types before querying.

View File

@ -95,7 +95,7 @@ field classes did not correctly convert their arguments:
* :class:`~django.db.models.FilePathField`
* :class:`~django.db.models.GenericIPAddressField`
* :class:`~django.db.models.IPAddressField`
* ``IPAddressField``
These three fields have been updated to convert their arguments to the
correct types before querying.

View File

@ -876,10 +876,8 @@ Miscellaneous
:class:`~django.forms.ModelMultipleChoiceField`.
* Some :attr:`~django.forms.Field.error_messages` for
:class:`~django.forms.IntegerField`,
:class:`~django.forms.EmailField`,
:class:`~django.forms.IPAddressField`,
:class:`~django.forms.GenericIPAddressField`, and
:class:`~django.forms.IntegerField`, :class:`~django.forms.EmailField`,
``IPAddressField``, :class:`~django.forms.GenericIPAddressField`, and
:class:`~django.forms.SlugField` have been suppressed because they
duplicated error messages already provided by validators tied to the fields.

View File

@ -1591,8 +1591,8 @@ better handle the case of selectively showing inlines on a ``ModelAdmin``.
``IPAddressField``
~~~~~~~~~~~~~~~~~~
The :class:`django.db.models.IPAddressField` and
:class:`django.forms.IPAddressField` fields have been deprecated in favor of
The ``django.db.models.IPAddressField`` and ``django.forms.IPAddressField``
fields have been deprecated in favor of
:class:`django.db.models.GenericIPAddressField` and
:class:`django.forms.GenericIPAddressField`.

View File

@ -29,7 +29,6 @@ class CaseTestModel(models.Model):
float = models.FloatField(null=True, db_column='float_field')
if Image:
image = models.ImageField(null=True)
ip_address = models.IPAddressField(null=True)
generic_ip_address = models.GenericIPAddressField(null=True)
null_boolean = models.NullBooleanField()
positive_integer = models.PositiveIntegerField(null=True)

View File

@ -752,21 +752,6 @@ class CaseExpressionTests(TestCase):
transform=lambda o: (o.integer, six.text_type(o.image))
)
def test_update_ip_address(self):
CaseTestModel.objects.update(
ip_address=Case(
# fails on postgresql if output_field is not set explicitly
When(integer=1, then=Value('1.1.1.1')),
When(integer=2, then=Value('2.2.2.2')),
output_field=models.IPAddressField(),
),
)
self.assertQuerysetEqual(
CaseTestModel.objects.all().order_by('pk'),
[(1, '1.1.1.1'), (2, '2.2.2.2'), (3, None), (2, '2.2.2.2'), (3, None), (3, None), (4, None)],
transform=attrgetter('integer', 'ip_address')
)
def test_update_generic_ip_address(self):
CaseTestModel.objects.update(
generic_ip_address=Case(

View File

@ -5,12 +5,11 @@ from django.core.files.uploadedfile import SimpleUploadedFile
from django.forms import (
BooleanField, CharField, ChoiceField, DateField, DateTimeField,
DecimalField, EmailField, FileField, FloatField, Form,
GenericIPAddressField, IntegerField, IPAddressField, ModelChoiceField,
GenericIPAddressField, IntegerField, ModelChoiceField,
ModelMultipleChoiceField, MultipleChoiceField, RegexField,
SplitDateTimeField, TimeField, URLField, utils, ValidationError,
)
from django.test import ignore_warnings, TestCase
from django.utils.deprecation import RemovedInDjango19Warning
from django.test import TestCase
from django.utils.safestring import mark_safe
from django.utils.encoding import python_2_unicode_compatible
@ -197,16 +196,6 @@ class FormsErrorMessagesTestCase(TestCase, AssertFormErrorsMixin):
self.assertFormErrors(['REQUIRED'], f.clean, '')
self.assertFormErrors(['INVALID DATE', 'INVALID TIME'], f.clean, ['a', 'b'])
@ignore_warnings(category=RemovedInDjango19Warning)
def test_ipaddressfield(self):
e = {
'required': 'REQUIRED',
'invalid': 'INVALID IP ADDRESS',
}
f = IPAddressField(error_messages=e)
self.assertFormErrors(['REQUIRED'], f.clean, '')
self.assertFormErrors(['INVALID IP ADDRESS'], f.clean, '127.0.0')
def test_generic_ipaddressfield(self):
e = {
'required': 'REQUIRED',

View File

@ -5,17 +5,16 @@ import datetime
from django.forms import (
CharField, DateField, EmailField, FileField, Form, GenericIPAddressField,
HiddenInput, ImageField, IPAddressField, MultipleChoiceField,
MultiValueField, MultiWidget, PasswordInput, SelectMultiple, SlugField,
SplitDateTimeField, SplitDateTimeWidget, TextInput, URLField,
HiddenInput, ImageField, MultipleChoiceField, MultiValueField, MultiWidget,
PasswordInput, SelectMultiple, SlugField, SplitDateTimeField,
SplitDateTimeWidget, TextInput, URLField,
)
from django.forms.extras import SelectDateWidget
from django.forms.utils import ErrorList
from django.test import TestCase, ignore_warnings, override_settings
from django.test import TestCase, override_settings
from django.utils import six
from django.utils import translation
from django.utils.dates import MONTHS_AP
from django.utils.deprecation import RemovedInDjango19Warning
from django.utils.encoding import force_text, smart_text, python_2_unicode_compatible
from .test_error_messages import AssertFormErrorsMixin
@ -483,26 +482,6 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
self.assertEqual(f.cleaned_data['field1'], 'some text,JP,2007-04-25 06:24:00')
@ignore_warnings(category=RemovedInDjango19Warning)
def test_ipaddress(self):
f = IPAddressField()
self.assertFormErrors(['This field is required.'], f.clean, '')
self.assertFormErrors(['This field is required.'], f.clean, None)
self.assertEqual(f.clean(' 127.0.0.1'), '127.0.0.1')
self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, 'foo')
self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '127.0.0.')
self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '1.2.3.4.5')
self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '256.125.1.5')
f = IPAddressField(required=False)
self.assertEqual(f.clean(''), '')
self.assertEqual(f.clean(None), '')
self.assertEqual(f.clean(' 127.0.0.1'), '127.0.0.1')
self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, 'foo')
self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '127.0.0.')
self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '1.2.3.4.5')
self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '256.125.1.5')
def test_generic_ipaddress_invalid_arguments(self):
self.assertRaises(ValueError, GenericIPAddressField, protocol="hamster")
self.assertRaises(ValueError, GenericIPAddressField, protocol="ipv4", unpack_ipv4=True)

View File

@ -59,7 +59,6 @@ class ColumnTypes(models.Model):
file_path_field = models.FilePathField()
float_field = models.FloatField()
int_field = models.IntegerField()
ip_address_field = models.IPAddressField()
gen_ip_adress_field = models.GenericIPAddressField(protocol="ipv4")
pos_int_field = models.PositiveIntegerField()
pos_small_int_field = models.PositiveSmallIntegerField()

View File

@ -61,11 +61,9 @@ class InspectDBTestCase(TestCase):
assertFieldType('file_field', "models.CharField(max_length=100)")
assertFieldType('file_path_field', "models.CharField(max_length=100)")
if connection.features.can_introspect_ip_address_field:
assertFieldType('ip_address_field', "models.GenericIPAddressField()")
assertFieldType('gen_ip_adress_field', "models.GenericIPAddressField()")
elif (connection.features.can_introspect_max_length and
not connection.features.interprets_empty_strings_as_nulls):
assertFieldType('ip_address_field', "models.CharField(max_length=15)")
assertFieldType('gen_ip_adress_field', "models.CharField(max_length=39)")
if (connection.features.can_introspect_max_length and
not connection.features.interprets_empty_strings_as_nulls):

View File

@ -0,0 +1,22 @@
from django.core import checks
from django.db import models
from .base import IsolatedModelsTestCase
class DeprecatedFieldssTests(IsolatedModelsTestCase):
def test_IPAddressField_deprecated(self):
class IPAddressModel(models.Model):
ip = models.IPAddressField()
model = IPAddressModel()
self.assertEqual(
model.check(),
[checks.Error(
'IPAddressField has been removed except for support in '
'historical migrations.',
hint='Use GenericIPAddressField instead.',
obj=IPAddressModel._meta.get_field('ip'),
id='fields.E900',
)],
)

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
]
operations = [
migrations.CreateModel(
name='IPAddressField',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('ip', models.IPAddressField(null=True, blank=True)),
],
),
]

View File

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('migrations', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='ipaddressfield',
name='ip',
),
]

View File

@ -0,0 +1,22 @@
from django.core.management import call_command
from django.test import override_settings
from .test_base import MigrationTestBase
class Tests(MigrationTestBase):
"""
Deprecated model fields should still be usable in historic migrations.
"""
@override_settings(MIGRATION_MODULES={"migrations": "migrations.deprecated_field_migrations"})
def test_migrate(self):
# Make sure no tables are created
self.assertTableNotExists("migrations_ipaddressfield")
# Run migration
call_command("migrate", verbosity=0)
# Make sure the right tables exist
self.assertTableExists("migrations_ipaddressfield")
# Unmigrate everything
call_command("migrate", "migrations", "zero", verbosity=0)
# Make sure it's all gone
self.assertTableNotExists("migrations_ipaddressfield")

View File

@ -168,16 +168,15 @@ class VerboseNameField(models.Model):
# Don't want to depend on Pillow in this test
#field_image = models.ImageField("verbose field")
field12 = models.IntegerField("verbose field12")
field13 = models.IPAddressField("verbose field13")
field14 = models.GenericIPAddressField("verbose field14", protocol="ipv4")
field15 = models.NullBooleanField("verbose field15")
field16 = models.PositiveIntegerField("verbose field16")
field17 = models.PositiveSmallIntegerField("verbose field17")
field18 = models.SlugField("verbose field18")
field19 = models.SmallIntegerField("verbose field19")
field20 = models.TextField("verbose field20")
field21 = models.TimeField("verbose field21")
field22 = models.URLField("verbose field22")
field13 = models.GenericIPAddressField("verbose field13", protocol="ipv4")
field14 = models.NullBooleanField("verbose field14")
field15 = models.PositiveIntegerField("verbose field15")
field16 = models.PositiveSmallIntegerField("verbose field16")
field17 = models.SlugField("verbose field17")
field18 = models.SmallIntegerField("verbose field18")
field19 = models.TextField("verbose field19")
field20 = models.TimeField("verbose field20")
field21 = models.URLField("verbose field21")
class GenericIPAddress(models.Model):
@ -323,7 +322,6 @@ class AllFieldsModel(models.Model):
file_path = models.FilePathField()
floatf = models.FloatField()
integer = models.IntegerField()
ip_address = models.IPAddressField()
generic_ip = models.GenericIPAddressField()
null_boolean = models.NullBooleanField()
positive_integer = models.PositiveIntegerField()

View File

@ -75,7 +75,7 @@ class BasicFieldTests(test.TestCase):
def test_field_verbose_name(self):
m = VerboseNameField
for i in range(1, 23):
for i in range(1, 22):
self.assertEqual(m._meta.get_field('field%d' % i).verbose_name,
'verbose field%d' % i)
@ -819,22 +819,6 @@ class PromiseTest(test.TestCase):
IPAddressField().get_prep_value(lazy_func()),
six.text_type)
def test_IPAddressField_deprecated(self):
class IPAddressModel(models.Model):
ip = IPAddressField()
model = IPAddressModel()
self.assertEqual(
model.check(),
[checks.Warning(
'IPAddressField has been deprecated. Support for it '
'(except in historical migrations) will be removed in Django 1.9.',
hint='Use GenericIPAddressField instead.',
obj=IPAddressModel._meta.get_field('ip'),
id='fields.W900',
)],
)
def test_GenericIPAddressField(self):
lazy_func = lazy(lambda: '127.0.0.1', six.text_type)
self.assertIsInstance(

View File

@ -65,10 +65,6 @@ class BigIntegerData(models.Model):
# data = models.ImageField(null=True)
class IPAddressData(models.Model):
data = models.IPAddressField(null=True)
class GenericIPAddressData(models.Model):
data = models.GenericIPAddressField(null=True)
@ -245,10 +241,6 @@ class IntegerPKData(models.Model):
# data = models.ImageField(primary_key=True)
class IPAddressPKData(models.Model):
data = models.IPAddressField(primary_key=True)
class GenericIPAddressPKData(models.Model):
data = models.GenericIPAddressField(primary_key=True)

View File

@ -28,13 +28,13 @@ from django.utils import six
from django.utils.functional import curry
from .models import (BinaryData, BooleanData, CharData, DateData, DateTimeData, EmailData,
FileData, FilePathData, DecimalData, FloatData, IntegerData, IPAddressData,
FileData, FilePathData, DecimalData, FloatData, IntegerData,
GenericIPAddressData, NullBooleanData, PositiveIntegerData,
PositiveSmallIntegerData, SlugData, SmallData, TextData, TimeData,
GenericData, Anchor, UniqueAnchor, FKData, M2MData, O2OData,
FKSelfData, M2MSelfData, FKDataToField, FKDataToO2O, M2MIntermediateData,
Intermediate, BooleanPKData, CharPKData, EmailPKData, FilePathPKData,
DecimalPKData, FloatPKData, IntegerPKData, IPAddressPKData,
DecimalPKData, FloatPKData, IntegerPKData,
GenericIPAddressPKData, PositiveIntegerPKData,
PositiveSmallIntegerPKData, SlugPKData, SmallPKData,
AutoNowDateTimeData, ModifyingSaveData, InheritAbstractModel, BaseModel,
@ -241,8 +241,6 @@ test_data = [
(data_obj, 82, IntegerData, 0),
(data_obj, 83, IntegerData, None),
#(XX, ImageData
(data_obj, 90, IPAddressData, "127.0.0.1"),
(data_obj, 91, IPAddressData, None),
(data_obj, 95, GenericIPAddressData, "fe80:1424:2223:6cff:fe8a:2e8a:2151:abcd"),
(data_obj, 96, GenericIPAddressData, None),
(data_obj, 100, NullBooleanData, True),
@ -341,7 +339,6 @@ The end."""),
(pk_obj, 681, IntegerPKData, -123456789),
(pk_obj, 682, IntegerPKData, 0),
# (XX, ImagePKData
(pk_obj, 690, IPAddressPKData, "127.0.0.1"),
(pk_obj, 695, GenericIPAddressPKData, "fe80:1424:2223:6cff:fe8a:2e8a:2151:abcd"),
# (pk_obj, 700, NullBooleanPKData, True),
# (pk_obj, 701, NullBooleanPKData, False),