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
5459795e
Kaydet (Commit)
5459795e
authored
May 21, 2013
tarafından
Anssi Kääriäinen
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #20289 -- pickling of dynamic models
üst
855d1305
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
70 additions
and
7 deletions
+70
-7
base.py
django/db/models/base.py
+18
-6
models.py
tests/queryset_pickle/models.py
+10
-0
tests.py
tests/queryset_pickle/tests.py
+42
-1
No files found.
django/db/models/base.py
Dosyayı görüntüle @
5459795e
...
...
@@ -451,16 +451,18 @@ class Model(six.with_metaclass(ModelBase)):
need to do things manually, as they're dynamically created classes and
only module-level classes can be pickled by the default path.
"""
if
not
self
.
_deferred
:
return
super
(
Model
,
self
)
.
__reduce__
()
data
=
self
.
__dict__
if
not
self
.
_deferred
:
class_id
=
self
.
_meta
.
app_label
,
self
.
_meta
.
object_name
return
model_unpickle
,
(
class_id
,
[],
simple_class_factory
),
data
defers
=
[]
for
field
in
self
.
_meta
.
fields
:
if
isinstance
(
self
.
__class__
.
__dict__
.
get
(
field
.
attname
),
DeferredAttribute
):
DeferredAttribute
):
defers
.
append
(
field
.
attname
)
model
=
self
.
_meta
.
proxy_for_model
return
(
model_unpickle
,
(
model
,
defers
),
data
)
class_id
=
model
.
_meta
.
app_label
,
model
.
_meta
.
object_name
return
(
model_unpickle
,
(
class_id
,
defers
,
deferred_class_factory
),
data
)
def
_get_pk_val
(
self
,
meta
=
None
):
if
not
meta
:
...
...
@@ -1008,12 +1010,22 @@ def get_absolute_url(opts, func, self, *args, **kwargs):
class
Empty
(
object
):
pass
def
simple_class_factory
(
model
,
attrs
):
"""
Needed for dynamic classes.
"""
return
model
def
model_unpickle
(
model
,
attrs
):
def
model_unpickle
(
model
_id
,
attrs
,
factory
):
"""
Used to unpickle Model subclasses with deferred fields.
"""
cls
=
deferred_class_factory
(
model
,
attrs
)
if
isinstance
(
model_id
,
tuple
):
model
=
get_model
(
*
model_id
)
else
:
# Backwards compat - the model was cached directly in earlier versions.
model
=
model_id
cls
=
factory
(
model
,
attrs
)
return
cls
.
__new__
(
cls
)
model_unpickle
.
__safe_for_unpickle__
=
True
...
...
tests/queryset_pickle/models.py
Dosyayı görüntüle @
5459795e
...
...
@@ -36,3 +36,13 @@ class Happening(models.Model):
number2
=
models
.
IntegerField
(
blank
=
True
,
default
=
Numbers
.
get_static_number
)
number3
=
models
.
IntegerField
(
blank
=
True
,
default
=
Numbers
.
get_class_number
)
number4
=
models
.
IntegerField
(
blank
=
True
,
default
=
nn
.
get_member_number
)
class
Container
(
object
):
# To test pickling we need a class that isn't defined on module, but
# is still available from app-cache. So, the Container class moves
# SomeModel outside of module level
class
SomeModel
(
models
.
Model
):
somefield
=
models
.
IntegerField
()
class
M2MModel
(
models
.
Model
):
groups
=
models
.
ManyToManyField
(
Group
)
tests/queryset_pickle/tests.py
Dosyayı görüntüle @
5459795e
...
...
@@ -3,9 +3,10 @@ from __future__ import absolute_import
import
pickle
import
datetime
from
django.db
import
models
from
django.test
import
TestCase
from
.models
import
Group
,
Event
,
Happening
from
.models
import
Group
,
Event
,
Happening
,
Container
,
M2MModel
class
PickleabilityTestCase
(
TestCase
):
...
...
@@ -49,3 +50,43 @@ class PickleabilityTestCase(TestCase):
# can't just use assertEqual(original, unpickled)
self
.
assertEqual
(
original
.
__class__
,
unpickled
.
__class__
)
self
.
assertEqual
(
original
.
args
,
unpickled
.
args
)
def
test_model_pickle
(
self
):
"""
Test that a model not defined on module level is pickleable.
"""
original
=
Container
.
SomeModel
(
pk
=
1
)
dumped
=
pickle
.
dumps
(
original
)
reloaded
=
pickle
.
loads
(
dumped
)
self
.
assertEqual
(
original
,
reloaded
)
# Also, deferred dynamic model works
Container
.
SomeModel
.
objects
.
create
(
somefield
=
1
)
original
=
Container
.
SomeModel
.
objects
.
defer
(
'somefield'
)[
0
]
dumped
=
pickle
.
dumps
(
original
)
reloaded
=
pickle
.
loads
(
dumped
)
self
.
assertEqual
(
original
,
reloaded
)
self
.
assertEqual
(
original
.
somefield
,
reloaded
.
somefield
)
def
test_model_pickle_m2m
(
self
):
"""
Test intentionally the automatically created through model.
"""
m1
=
M2MModel
.
objects
.
create
()
g1
=
Group
.
objects
.
create
(
name
=
'foof'
)
m1
.
groups
.
add
(
g1
)
m2m_through
=
M2MModel
.
_meta
.
get_field_by_name
(
'groups'
)[
0
]
.
rel
.
through
original
=
m2m_through
.
objects
.
get
()
dumped
=
pickle
.
dumps
(
original
)
reloaded
=
pickle
.
loads
(
dumped
)
self
.
assertEqual
(
original
,
reloaded
)
def
test_model_pickle_dynamic
(
self
):
class
Meta
:
proxy
=
True
dynclass
=
type
(
"DynamicEventSubclass"
,
(
Event
,
),
{
'Meta'
:
Meta
,
'__module__'
:
Event
.
__module__
})
original
=
dynclass
(
pk
=
1
)
dumped
=
pickle
.
dumps
(
original
)
reloaded
=
pickle
.
loads
(
dumped
)
self
.
assertEqual
(
original
,
reloaded
)
self
.
assertIs
(
reloaded
.
__class__
,
dynclass
)
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