Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
c87ee419
Kaydet (Commit)
c87ee419
authored
Ock 01, 2015
tarafından
Tim Graham
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #23861 -- Added an API to deprecate model fields.
Thanks Markus Holterman and Berker Peksag for review.
üst
6e1c9c65
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
173 additions
and
13 deletions
+173
-13
__init__.py
django/db/models/fields/__init__.py
+39
-13
1.8.txt
docs/releases/1.8.txt
+3
-0
migrations.txt
docs/topics/migrations.txt
+48
-0
test_model_field_deprecation.py
tests/check_framework/test_model_field_deprecation.py
+83
-0
No files found.
django/db/models/fields/__init__.py
Dosyayı görüntüle @
c87ee419
...
@@ -113,6 +113,8 @@ class Field(RegisterLookupMixin):
...
@@ -113,6 +113,8 @@ class Field(RegisterLookupMixin):
"
%(date_field_label)
s
%(lookup_type)
s."
),
"
%(date_field_label)
s
%(lookup_type)
s."
),
}
}
class_lookups
=
default_lookups
.
copy
()
class_lookups
=
default_lookups
.
copy
()
system_check_deprecated_details
=
None
system_check_removed_details
=
None
# Generic field type description, usually overridden by subclasses
# Generic field type description, usually overridden by subclasses
def
_description
(
self
):
def
_description
(
self
):
...
@@ -191,6 +193,7 @@ class Field(RegisterLookupMixin):
...
@@ -191,6 +193,7 @@ class Field(RegisterLookupMixin):
errors
.
extend
(
self
.
_check_db_index
())
errors
.
extend
(
self
.
_check_db_index
())
errors
.
extend
(
self
.
_check_null_allowed_for_primary_keys
())
errors
.
extend
(
self
.
_check_null_allowed_for_primary_keys
())
errors
.
extend
(
self
.
_check_backend_specific_checks
(
**
kwargs
))
errors
.
extend
(
self
.
_check_backend_specific_checks
(
**
kwargs
))
errors
.
extend
(
self
.
_check_deprecation_details
())
return
errors
return
errors
def
_check_field_name
(
self
):
def
_check_field_name
(
self
):
...
@@ -290,6 +293,34 @@ class Field(RegisterLookupMixin):
...
@@ -290,6 +293,34 @@ class Field(RegisterLookupMixin):
def
_check_backend_specific_checks
(
self
,
**
kwargs
):
def
_check_backend_specific_checks
(
self
,
**
kwargs
):
return
connection
.
validation
.
check_field
(
self
,
**
kwargs
)
return
connection
.
validation
.
check_field
(
self
,
**
kwargs
)
def
_check_deprecation_details
(
self
):
if
self
.
system_check_removed_details
is
not
None
:
return
[
checks
.
Error
(
self
.
system_check_removed_details
.
get
(
'msg'
,
'
%
s has been removed except for support in historical '
'migrations.'
%
self
.
__class__
.
__name__
),
hint
=
self
.
system_check_removed_details
.
get
(
'hint'
),
obj
=
self
,
id
=
self
.
system_check_removed_details
.
get
(
'id'
,
'fields.EXXX'
),
)
]
elif
self
.
system_check_deprecated_details
is
not
None
:
return
[
checks
.
Warning
(
self
.
system_check_deprecated_details
.
get
(
'msg'
,
'
%
s has been deprecated.'
%
self
.
__class__
.
__name__
),
hint
=
self
.
system_check_deprecated_details
.
get
(
'hint'
),
obj
=
self
,
id
=
self
.
system_check_deprecated_details
.
get
(
'id'
,
'fields.WXXX'
),
)
]
return
[]
def
deconstruct
(
self
):
def
deconstruct
(
self
):
"""
"""
Returns enough information to recreate the field as a 4-tuple:
Returns enough information to recreate the field as a 4-tuple:
...
@@ -1832,6 +1863,14 @@ class BigIntegerField(IntegerField):
...
@@ -1832,6 +1863,14 @@ class BigIntegerField(IntegerField):
class
IPAddressField
(
Field
):
class
IPAddressField
(
Field
):
empty_strings_allowed
=
False
empty_strings_allowed
=
False
description
=
_
(
"IPv4 address"
)
description
=
_
(
"IPv4 address"
)
system_check_deprecated_details
=
{
'msg'
:
(
'IPAddressField has been deprecated. Support for it (except in '
'historical migrations) will be removed in Django 1.9.'
),
'hint'
:
'Use GenericIPAddressField instead.'
,
'id'
:
'fields.W900'
,
}
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
kwargs
[
'max_length'
]
=
15
kwargs
[
'max_length'
]
=
15
...
@@ -1856,19 +1895,6 @@ class IPAddressField(Field):
...
@@ -1856,19 +1895,6 @@ class IPAddressField(Field):
defaults
.
update
(
kwargs
)
defaults
.
update
(
kwargs
)
return
super
(
IPAddressField
,
self
)
.
formfield
(
**
defaults
)
return
super
(
IPAddressField
,
self
)
.
formfield
(
**
defaults
)
def
check
(
self
,
**
kwargs
):
errors
=
super
(
IPAddressField
,
self
)
.
check
(
**
kwargs
)
errors
.
append
(
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
=
self
,
id
=
'fields.W900'
,
)
)
return
errors
class
GenericIPAddressField
(
Field
):
class
GenericIPAddressField
(
Field
):
empty_strings_allowed
=
True
empty_strings_allowed
=
True
...
...
docs/releases/1.8.txt
Dosyayı görüntüle @
c87ee419
...
@@ -438,6 +438,9 @@ Migrations
...
@@ -438,6 +438,9 @@ Migrations
* Migrations can now :ref:`serialize model managers
* Migrations can now :ref:`serialize model managers
<using-managers-in-migrations>` as part of the model state.
<using-managers-in-migrations>` as part of the model state.
* A :ref:`generic mechanism to handle the deprecation of model fields
<migrations-removing-model-fields>` was added.
Models
Models
^^^^^^
^^^^^^
...
...
docs/topics/migrations.txt
Dosyayı görüntüle @
c87ee419
...
@@ -387,6 +387,54 @@ contains a reference to them. On the plus side, methods and managers from these
...
@@ -387,6 +387,54 @@ contains a reference to them. On the plus side, methods and managers from these
base classes inherit normally, so if you absolutely need access to these you
base classes inherit normally, so if you absolutely need access to these you
can opt to move them into a superclass.
can opt to move them into a superclass.
.. _migrations-removing-model-fields:
Considerations when removing model fields
-----------------------------------------
.. versionadded:: 1.8
Similar to the "references to historical functions" considerations described in
the previous section, removing custom model fields from your project or
third-party app will cause a problem if they are referenced in old migrations.
To help with this situation, Django provides some model field attributes to
assist with model field deprecation using the :doc:`system checks framework
</topics/checks>`.
Add the ``system_check_deprecated_details`` attribute to your model field
similar to the following::
class IPAddressField(Field):
system_check_deprecated_details = {
'msg': (
'IPAddressField has been deprecated. Support for it (except '
'in historical migrations) will be removed in Django 1.9.'
),
'hint': 'Use GenericIPAddressField instead.', # optional
'id': 'fields.W900', # pick a unique ID for your field.
}
After a deprecation period of your choosing (two major releases for fields in
Django itself), change the ``system_check_deprecated_details`` attribute to
``system_check_removed_details`` and update the dictionary similar to::
class IPAddressField(Field):
system_check_removed_details = {
'msg': (
'IPAddressField has been removed except for support in '
'historical migrations.'
),
'hint': 'Use GenericIPAddressField instead.',
'id': 'fields.E900', # pick a unique ID for your field.
}
You should keep the field's methods that are required for it to operate in
database migrations such as ``__init__()``, ``deconstruct()``, and
``get_internal_type()``. Keep this stub field for as long as any migrations
which reference the field exist. For example, after squashing migrations and
removing the old ones, you should be able to remove the field completely.
.. _data-migrations:
.. _data-migrations:
Data Migrations
Data Migrations
...
...
tests/check_framework/test_model_field_deprecation.py
0 → 100644
Dosyayı görüntüle @
c87ee419
from
django.db
import
models
from
django.core
import
checks
from
django.test
import
SimpleTestCase
class
TestDeprecatedField
(
SimpleTestCase
):
def
test_default_details
(
self
):
class
MyField
(
models
.
Field
):
system_check_deprecated_details
=
{}
class
Model
(
models
.
Model
):
name
=
MyField
()
model
=
Model
()
self
.
assertEqual
(
model
.
check
(),
[
checks
.
Warning
(
msg
=
'MyField has been deprecated.'
,
hint
=
None
,
obj
=
Model
.
_meta
.
get_field
(
'name'
),
id
=
'fields.WXXX'
,
)
])
def
test_user_specified_details
(
self
):
class
MyField
(
models
.
Field
):
system_check_deprecated_details
=
{
'msg'
:
'This field is deprecated and will be removed soon.'
,
'hint'
:
'Use something else.'
,
'id'
:
'fields.W999'
,
}
class
Model
(
models
.
Model
):
name
=
MyField
()
model
=
Model
()
self
.
assertEqual
(
model
.
check
(),
[
checks
.
Warning
(
msg
=
'This field is deprecated and will be removed soon.'
,
hint
=
'Use something else.'
,
obj
=
Model
.
_meta
.
get_field
(
'name'
),
id
=
'fields.W999'
,
)
])
class
TestRemovedField
(
SimpleTestCase
):
def
test_default_details
(
self
):
class
MyField
(
models
.
Field
):
system_check_removed_details
=
{}
class
Model
(
models
.
Model
):
name
=
MyField
()
model
=
Model
()
self
.
assertEqual
(
model
.
check
(),
[
checks
.
Error
(
msg
=
'MyField has been removed except for support in historical migrations.'
,
hint
=
None
,
obj
=
Model
.
_meta
.
get_field
(
'name'
),
id
=
'fields.EXXX'
,
)
])
def
test_user_specified_details
(
self
):
class
MyField
(
models
.
Field
):
system_check_removed_details
=
{
'msg'
:
'Support for this field is gone.'
,
'hint'
:
'Use something else.'
,
'id'
:
'fields.E999'
,
}
class
Model
(
models
.
Model
):
name
=
MyField
()
model
=
Model
()
self
.
assertEqual
(
model
.
check
(),
[
checks
.
Error
(
msg
=
'Support for this field is gone.'
,
hint
=
'Use something else.'
,
obj
=
Model
.
_meta
.
get_field
(
'name'
),
id
=
'fields.E999'
,
)
])
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment