Skip to content

Commit efa1bb1

Browse files
author
Jan Schrewe
committed
We don't need no recursion for jschrewe#60
1 parent d8c16b5 commit efa1bb1

File tree

2 files changed

+66
-7
lines changed

2 files changed

+66
-7
lines changed

mongodbforms/documentoptions.py

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from django.db.models.fields import FieldDoesNotExist
66
from django.utils.text import capfirst
77
from django.db.models.options import get_verbose_name
8+
from django.utils.functional import LazyObject, empty
89

910
from mongoengine.fields import ReferenceField, ListField
1011

@@ -57,6 +58,56 @@ def __setattr__(self, attr, value):
5758
super(PkWrapper, self).__setattr__(attr, value)
5859

5960

61+
class LazyDocumentMetaWrapper(LazyObject):
62+
_document = None
63+
_meta = None
64+
65+
def __init__(self, document):
66+
self._document = document
67+
self._meta = document._meta
68+
super(LazyDocumentMetaWrapper, self).__init__()
69+
70+
def _setup(self):
71+
self._wrapped = DocumentMetaWrapper(self._document, self._meta)
72+
73+
def __setattr__(self, name, value):
74+
if name in ["_document", "_meta",]:
75+
# Assign to __dict__ to avoid infinite __setattr__ loops.
76+
object.__setattr__(self, name, value)
77+
else:
78+
super(LazyDocumentMetaWrapper, self).__setattr__(name, value)
79+
80+
def __dir__(self):
81+
if self._wrapped is empty:
82+
self._setup()
83+
return self._wrapped.__dir__()
84+
85+
def __getitem__(self, key):
86+
if self._wrapped is empty:
87+
self._setup()
88+
return self._wrapped.__getitem__(key)
89+
90+
def __setitem__(self, key, value):
91+
if self._wrapped is empty:
92+
self._setup()
93+
return self._wrapped.__getitem__(key, value)
94+
95+
def __delitem__(self, key):
96+
if self._wrapped is empty:
97+
self._setup()
98+
return self._wrapped.__delitem__(key)
99+
100+
def __len__(self):
101+
if self._wrapped is empty:
102+
self._setup()
103+
return self._wrapped.__len__()
104+
105+
def __contains__(self, key):
106+
if self._wrapped is empty:
107+
self._setup()
108+
return self._wrapped.__contains__(key)
109+
110+
60111
class DocumentMetaWrapper(MutableMapping):
61112
"""
62113
Used to store mongoengine's _meta dict to make the document admin
@@ -81,14 +132,19 @@ class DocumentMetaWrapper(MutableMapping):
81132
concrete_model = None
82133
concrete_managers = []
83134

84-
def __init__(self, document):
135+
def __init__(self, document, meta=None):
85136
super(DocumentMetaWrapper, self).__init__()
86137

138+
print "__init__'s document is:"
139+
print type(document)
87140
self.document = document
88141
# used by Django to distinguish between abstract and concrete models
89142
# here for now always the document
90143
self.concrete_model = document
91-
self._meta = getattr(document, '_meta', {})
144+
if meta is None:
145+
self._meta = getattr(document, '_meta', {})
146+
else:
147+
self._meta = meta
92148

93149
try:
94150
self.object_name = self.document.__name__
@@ -131,9 +187,10 @@ def _setup_document_fields(self):
131187
flat.append((choice, value))
132188
f.flatchoices = flat
133189
if isinstance(f, ReferenceField) and not \
134-
isinstance(f.document_type._meta, DocumentMetaWrapper) \
135-
and self.document != f.document_type:
136-
f.document_type._meta = DocumentMetaWrapper(f.document_type)
190+
isinstance(f.document_type._meta, DocumentMetaWrapper) and not \
191+
isinstance(f.document_type._meta, LazyDocumentMetaWrapper) and \
192+
self.document != f.document_type:
193+
f.document_type._meta = LazyDocumentMetaWrapper(f.document_type)
137194

138195
def _init_pk(self):
139196
"""

mongodbforms/util.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from django.conf import settings
44

5-
from .documentoptions import DocumentMetaWrapper
5+
from mongodbforms.documentoptions import DocumentMetaWrapper, LazyDocumentMetaWrapper
66
from .fieldgenerator import MongoDefaultFormFieldGenerator
77

88
try:
@@ -50,7 +50,9 @@ def load_field_generator():
5050

5151

5252
def init_document_options(document):
53-
if not isinstance(document._meta, DocumentMetaWrapper):
53+
if not (isinstance(document._meta, DocumentMetaWrapper) or
54+
isinstance(document._meta, LazyDocumentMetaWrapper)):
55+
print "setting up wrapper for meta of type %s" % type(document._meta)
5456
document._meta = DocumentMetaWrapper(document)
5557
return document
5658

0 commit comments

Comments
 (0)