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
08ab2626
Kaydet (Commit)
08ab2626
authored
Agu 12, 2015
tarafından
Tim Graham
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Removed SubfieldBase per deprecation timeline.
üst
4fd264b6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
2 additions
and
312 deletions
+2
-312
__init__.py
django/db/models/__init__.py
+0
-1
subclassing.py
django/db/models/fields/subclassing.py
+0
-63
custom-model-fields.txt
docs/howto/custom-model-fields.txt
+0
-7
fields.py
tests/field_subclassing/fields.py
+0
-88
models.py
tests/field_subclassing/models.py
+0
-34
tests.py
tests/field_subclassing/tests.py
+2
-119
No files found.
django/db/models/__init__.py
Dosyayı görüntüle @
08ab2626
...
...
@@ -12,7 +12,6 @@ from django.db.models.expressions import ( # NOQA
from
django.db.models.fields
import
*
# NOQA
from
django.db.models.fields.files
import
FileField
,
ImageField
# NOQA
from
django.db.models.fields.proxy
import
OrderWrt
# NOQA
from
django.db.models.fields.subclassing
import
SubfieldBase
# NOQA
from
django.db.models.lookups
import
Lookup
,
Transform
# NOQA
from
django.db.models.manager
import
Manager
# NOQA
from
django.db.models.query
import
Q
,
Prefetch
,
QuerySet
# NOQA
...
...
django/db/models/fields/subclassing.py
deleted
100644 → 0
Dosyayı görüntüle @
4fd264b6
"""
Convenience routines for creating non-trivial Field subclasses, as well as
backwards compatibility utilities.
Add SubfieldBase as the metaclass for your Field subclass, implement
to_python() and the other necessary methods and everything will work
seamlessly.
"""
import
warnings
from
django.utils.deprecation
import
RemovedInDjango110Warning
class
SubfieldBase
(
type
):
"""
A metaclass for custom Field subclasses. This ensures the model's attribute
has the descriptor protocol attached to it.
"""
def
__new__
(
cls
,
name
,
bases
,
attrs
):
warnings
.
warn
(
"SubfieldBase has been deprecated. Use Field.from_db_value instead."
,
RemovedInDjango110Warning
)
new_class
=
super
(
SubfieldBase
,
cls
)
.
__new__
(
cls
,
name
,
bases
,
attrs
)
new_class
.
contribute_to_class
=
make_contrib
(
new_class
,
attrs
.
get
(
'contribute_to_class'
)
)
return
new_class
class
Creator
(
object
):
"""
A placeholder class that provides a way to set the attribute on the model.
"""
def
__init__
(
self
,
field
):
self
.
field
=
field
def
__get__
(
self
,
obj
,
type
=
None
):
if
obj
is
None
:
return
self
return
obj
.
__dict__
[
self
.
field
.
name
]
def
__set__
(
self
,
obj
,
value
):
obj
.
__dict__
[
self
.
field
.
name
]
=
self
.
field
.
to_python
(
value
)
def
make_contrib
(
superclass
,
func
=
None
):
"""
Returns a suitable contribute_to_class() method for the Field subclass.
If 'func' is passed in, it is the existing contribute_to_class() method on
the subclass and it is called before anything else. It is assumed in this
case that the existing contribute_to_class() calls all the necessary
superclass methods.
"""
def
contribute_to_class
(
self
,
cls
,
name
,
**
kwargs
):
if
func
:
func
(
self
,
cls
,
name
,
**
kwargs
)
else
:
super
(
superclass
,
self
)
.
contribute_to_class
(
cls
,
name
,
**
kwargs
)
setattr
(
cls
,
self
.
name
,
Creator
(
self
))
return
contribute_to_class
docs/howto/custom-model-fields.txt
Dosyayı görüntüle @
08ab2626
...
...
@@ -428,13 +428,6 @@ get out of the way.
Converting values to Python objects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. versionchanged:: 1.8
Historically, Django provided a metaclass called ``SubfieldBase`` which
always called :meth:`~Field.to_python` on assignment. This did not play
nicely with custom database transformations, aggregation, or values
queries, so it has been replaced with :meth:`~Field.from_db_value`.
If your custom :class:`~Field` class deals with data structures that are more
complex than strings, dates, integers, or floats, then you may need to override
:meth:`~Field.from_db_value` and :meth:`~Field.to_python`.
...
...
tests/field_subclassing/fields.py
Dosyayı görüntüle @
08ab2626
from
__future__
import
unicode_literals
import
json
import
warnings
from
django.db
import
models
from
django.utils
import
six
from
django.utils.deconstruct
import
deconstructible
from
django.utils.deprecation
import
RemovedInDjango110Warning
from
django.utils.encoding
import
force_text
,
python_2_unicode_compatible
# Catch warning about subfieldbase -- remove in Django 1.10
warnings
.
filterwarnings
(
'ignore'
,
'SubfieldBase has been deprecated. Use Field.from_db_value instead.'
,
RemovedInDjango110Warning
)
@deconstructible
@python_2_unicode_compatible
class
Small
(
object
):
"""
A simple class to show that non-trivial Python objects can be used as
attributes.
"""
def
__init__
(
self
,
first
,
second
):
self
.
first
,
self
.
second
=
first
,
second
def
__str__
(
self
):
return
'
%
s
%
s'
%
(
force_text
(
self
.
first
),
force_text
(
self
.
second
))
def
__eq__
(
self
,
other
):
if
isinstance
(
other
,
self
.
__class__
):
return
self
.
first
==
other
.
first
and
self
.
second
==
other
.
second
return
False
class
SmallField
(
six
.
with_metaclass
(
models
.
SubfieldBase
,
models
.
Field
)):
"""
Turns the "Small" class into a Django field. Because of the similarities
with normal character fields and the fact that Small.__unicode__ does
something sensible, we don't need to implement a lot here.
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
kwargs
[
'max_length'
]
=
2
super
(
SmallField
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
def
get_internal_type
(
self
):
return
'CharField'
def
to_python
(
self
,
value
):
if
isinstance
(
value
,
Small
):
return
value
return
Small
(
value
[
0
],
value
[
1
])
def
get_db_prep_save
(
self
,
value
,
connection
):
return
six
.
text_type
(
value
)
def
get_prep_lookup
(
self
,
lookup_type
,
value
):
if
lookup_type
==
'exact'
:
return
force_text
(
value
)
if
lookup_type
==
'in'
:
return
[
force_text
(
v
)
for
v
in
value
]
if
lookup_type
==
'isnull'
:
return
[]
raise
TypeError
(
'Invalid lookup type:
%
r'
%
lookup_type
)
class
SmallerField
(
SmallField
):
pass
class
JSONField
(
six
.
with_metaclass
(
models
.
SubfieldBase
,
models
.
TextField
)):
description
=
(
"JSONField automatically serializes and deserializes values to "
"and from JSON."
)
def
to_python
(
self
,
value
):
if
not
value
:
return
None
if
isinstance
(
value
,
six
.
string_types
):
value
=
json
.
loads
(
value
)
return
value
def
get_db_prep_save
(
self
,
value
,
connection
):
if
value
is
None
:
return
None
return
json
.
dumps
(
value
)
class
CustomTypedField
(
models
.
TextField
):
...
...
tests/field_subclassing/models.py
deleted
100644 → 0
Dosyayı görüntüle @
4fd264b6
"""
Tests for field subclassing.
"""
from
django.db
import
models
from
django.utils.encoding
import
force_text
,
python_2_unicode_compatible
from
.fields
import
JSONField
,
Small
,
SmallerField
,
SmallField
@python_2_unicode_compatible
class
MyModel
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
10
)
data
=
SmallField
(
'small field'
)
def
__str__
(
self
):
return
force_text
(
self
.
name
)
class
OtherModel
(
models
.
Model
):
data
=
SmallerField
()
class
ChoicesModel
(
models
.
Model
):
SMALL_AB
=
Small
(
'a'
,
'b'
)
SMALL_CD
=
Small
(
'c'
,
'd'
)
SMALL_CHOICES
=
(
(
SMALL_AB
,
str
(
SMALL_AB
)),
(
SMALL_CD
,
str
(
SMALL_CD
)),
)
data
=
SmallField
(
'small field'
,
choices
=
SMALL_CHOICES
)
class
DataModel
(
models
.
Model
):
data
=
JSONField
()
tests/field_subclassing/tests.py
Dosyayı görüntüle @
08ab2626
from
__future__
import
unicode_literals
import
inspect
from
django.core
import
exceptions
,
serializers
from
django.db
import
connection
from
django.test
import
SimpleTestCase
,
TestCase
from
.fields
import
CustomTypedField
,
Small
from
.models
import
ChoicesModel
,
DataModel
,
MyModel
,
OtherModel
class
CustomField
(
TestCase
):
def
test_refresh
(
self
):
d
=
DataModel
.
objects
.
create
(
data
=
[
1
,
2
,
3
])
d
.
refresh_from_db
(
fields
=
[
'data'
])
self
.
assertIsInstance
(
d
.
data
,
list
)
self
.
assertEqual
(
d
.
data
,
[
1
,
2
,
3
])
def
test_defer
(
self
):
d
=
DataModel
.
objects
.
create
(
data
=
[
1
,
2
,
3
])
self
.
assertIsInstance
(
d
.
data
,
list
)
d
=
DataModel
.
objects
.
get
(
pk
=
d
.
pk
)
self
.
assertIsInstance
(
d
.
data
,
list
)
self
.
assertEqual
(
d
.
data
,
[
1
,
2
,
3
])
d
=
DataModel
.
objects
.
defer
(
"data"
)
.
get
(
pk
=
d
.
pk
)
self
.
assertIsInstance
(
d
.
data
,
list
)
self
.
assertEqual
(
d
.
data
,
[
1
,
2
,
3
])
# Refetch for save
d
=
DataModel
.
objects
.
defer
(
"data"
)
.
get
(
pk
=
d
.
pk
)
d
.
save
()
d
=
DataModel
.
objects
.
get
(
pk
=
d
.
pk
)
self
.
assertIsInstance
(
d
.
data
,
list
)
self
.
assertEqual
(
d
.
data
,
[
1
,
2
,
3
])
def
test_custom_field
(
self
):
# Creating a model with custom fields is done as per normal.
s
=
Small
(
1
,
2
)
self
.
assertEqual
(
str
(
s
),
"12"
)
m
=
MyModel
.
objects
.
create
(
name
=
"m"
,
data
=
s
)
# Custom fields still have normal field's attributes.
self
.
assertEqual
(
m
.
_meta
.
get_field
(
"data"
)
.
verbose_name
,
"small field"
)
# The m.data attribute has been initialized correctly. It's a Small
# object.
self
.
assertEqual
((
m
.
data
.
first
,
m
.
data
.
second
),
(
1
,
2
))
# The data loads back from the database correctly and 'data' has the
# right type.
m1
=
MyModel
.
objects
.
get
(
pk
=
m
.
pk
)
self
.
assertIsInstance
(
m1
.
data
,
Small
)
self
.
assertEqual
(
str
(
m1
.
data
),
"12"
)
# We can do normal filtering on the custom field (and will get an error
# when we use a lookup type that does not make sense).
s1
=
Small
(
1
,
3
)
s2
=
Small
(
"a"
,
"b"
)
self
.
assertQuerysetEqual
(
MyModel
.
objects
.
filter
(
data__in
=
[
s
,
s1
,
s2
]),
[
"m"
,
],
lambda
m
:
m
.
name
,
)
self
.
assertRaises
(
TypeError
,
lambda
:
MyModel
.
objects
.
filter
(
data__lt
=
s
))
# Serialization works, too.
stream
=
serializers
.
serialize
(
"json"
,
MyModel
.
objects
.
all
())
self
.
assertJSONEqual
(
stream
,
[{
"pk"
:
m1
.
pk
,
"model"
:
"field_subclassing.mymodel"
,
"fields"
:
{
"data"
:
"12"
,
"name"
:
"m"
}
}])
obj
=
list
(
serializers
.
deserialize
(
"json"
,
stream
))[
0
]
self
.
assertEqual
(
obj
.
object
,
m
)
# Test retrieving custom field data
m
.
delete
()
m1
=
MyModel
.
objects
.
create
(
name
=
"1"
,
data
=
Small
(
1
,
2
))
MyModel
.
objects
.
create
(
name
=
"2"
,
data
=
Small
(
2
,
3
))
self
.
assertQuerysetEqual
(
MyModel
.
objects
.
all
(),
[
"12"
,
"23"
,
],
lambda
m
:
str
(
m
.
data
),
ordered
=
False
)
def
test_field_subclassing
(
self
):
o
=
OtherModel
.
objects
.
create
(
data
=
Small
(
"a"
,
"b"
))
o
=
OtherModel
.
objects
.
get
()
self
.
assertEqual
(
o
.
data
.
first
,
"a"
)
self
.
assertEqual
(
o
.
data
.
second
,
"b"
)
def
test_subfieldbase_plays_nice_with_module_inspect
(
self
):
"""
Custom fields should play nice with python standard module inspect.
http://users.rcn.com/python/download/Descriptor.htm#properties
"""
# Even when looking for totally different properties, SubfieldBase's
# non property like behavior made inspect crash. Refs #12568.
data
=
dict
(
inspect
.
getmembers
(
MyModel
))
self
.
assertIn
(
'__module__'
,
data
)
self
.
assertEqual
(
data
[
'__module__'
],
'field_subclassing.models'
)
def
test_validation_of_choices_for_custom_field
(
self
):
# a valid choice
o
=
ChoicesModel
.
objects
.
create
(
data
=
Small
(
'a'
,
'b'
))
o
.
full_clean
()
from
django.test
import
SimpleTestCase
# an invalid choice
o
=
ChoicesModel
.
objects
.
create
(
data
=
Small
(
'd'
,
'e'
))
with
self
.
assertRaises
(
exceptions
.
ValidationError
):
o
.
full_clean
()
from
.fields
import
CustomTypedField
class
TestDbType
(
SimpleTestCase
):
...
...
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