Skip to content

Commit 66e1938

Browse files
author
Carlos Ramirez
committed
Merge remote-tracking branch 'master/master' into d110
Conflicts: mongodbforms/documentoptions.py mongodbforms/documents.py
2 parents 79c206f + 9d7e48d commit 66e1938

File tree

8 files changed

+263
-203
lines changed

8 files changed

+263
-203
lines changed

mongodbforms/documentoptions.py

Lines changed: 79 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@
44

55
from django.db.models.fields import FieldDoesNotExist
66
from django.utils.text import capfirst
7-
# from django.db.models.options import get_verbose_name
8-
from django.utils.functional import LazyObject
7+
from django.utils.functional import LazyObject, new_method_proxy
8+
try:
9+
# New in Django 1.7+
10+
from django.utils.text import camel_case_to_spaces
11+
except ImportError:
12+
# Backwards compatibility
13+
from django.db.models.options import get_verbose_name as camel_case_to_spaces
914
from django.conf import settings
10-
1115
from mongoengine.fields import ReferenceField, ListField
1216

13-
# TODO: validate it. This is added instead of django get_verbose_name
14-
import re
15-
get_verbose_name = lambda class_name: re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', ' \\1', class_name).lower().strip()
1617

1718
def patch_document(function, instance, bound=True):
1819
if bound:
@@ -23,7 +24,7 @@ def patch_document(function, instance, bound=True):
2324

2425

2526
def create_verbose_name(name):
26-
name = get_verbose_name(name)
27+
name = camel_case_to_spaces(name)
2728
name = name.replace('_', ' ')
2829
return name
2930

@@ -50,26 +51,10 @@ def to(self, value):
5051
class PkWrapper(object):
5152
editable = False
5253
fake = False
53-
# TODO: check it. Probably will be used to accomplished django 1.7
54-
# rel = None
55-
# blank = True
56-
# null = True
57-
# verbose_name = None
58-
# help_text = None
59-
# flatchoices = False
6054

6155
def __init__(self, wrapped):
6256
self.obj = wrapped
6357

64-
# def has_default(self):
65-
# return False
66-
#
67-
# def _get_val_from_obj(self, obj):
68-
# return obj
69-
#
70-
# def value_to_string(self, obj):
71-
# return str(obj)
72-
7358
def __getattr__(self, attr):
7459
if attr in dir(self.obj):
7560
return getattr(self.obj, attr)
@@ -84,39 +69,27 @@ def __setattr__(self, attr, value):
8469
class LazyDocumentMetaWrapper(LazyObject):
8570
_document = None
8671
_meta = None
87-
72+
8873
def __init__(self, document):
8974
self._document = document
9075
self._meta = document._meta
9176
super(LazyDocumentMetaWrapper, self).__init__()
92-
77+
9378
def _setup(self):
9479
self._wrapped = DocumentMetaWrapper(self._document, self._meta)
95-
80+
9681
def __setattr__(self, name, value):
97-
if name in ["_document", "_meta",]:
82+
if name in ["_document", "_meta", ]:
9883
object.__setattr__(self, name, value)
9984
else:
10085
super(LazyDocumentMetaWrapper, self).__setattr__(name, value)
101-
102-
def __dir__(self):
103-
return self._wrapped.__dir__()
104-
105-
def __getitem__(self, key):
106-
return self._wrapped.__getitem__(key)
107-
108-
def __setitem__(self, key, value):
109-
return self._wrapped.__getitem__(key)
110-
111-
def __delitem__(self, key):
112-
return self._wrapped.__delitem__(key)
113-
114-
def __len__(self):
115-
return self._wrapped.__len__()
116-
86+
87+
__len__ = new_method_proxy(len)
88+
89+
@new_method_proxy
11790
def __contains__(self, key):
118-
return self._wrapped.__contains__(key)
119-
91+
return key in self
92+
12093

12194
class DocumentMetaWrapper(MutableMapping):
12295
"""
@@ -129,12 +102,12 @@ class DocumentMetaWrapper(MutableMapping):
129102
pk = None
130103
pk_name = None
131104
_app_label = None
132-
_app_config = None
133105
model_name = None
134106
_verbose_name = None
135107
has_auto_field = False
136108
object_name = None
137109
proxy = []
110+
proxied_children = []
138111
parents = {}
139112
many_to_many = []
140113
_field_cache = None
@@ -154,10 +127,18 @@ def __init__(self, document, meta=None):
154127
self.concrete_model = document
155128
if meta is None:
156129
meta = getattr(document, '_meta', {})
130+
if not 'app_label' in meta:
131+
meta['app_label'] = document.__module__.split('.')[0]
132+
if not 'app_config' in meta:
133+
# TODO: this needs improvements
134+
meta['app_config'] = dict()
135+
if not 'verbose_name' in meta:
136+
meta['app_config']['verbose_name'] = meta['app_label'].replace('_', ' ').capitalize()
157137
if isinstance(meta, LazyDocumentMetaWrapper):
158138
meta = meta._meta
159139
self._meta = meta
160140

141+
161142
try:
162143
self.object_name = self.document.__name__
163144
except AttributeError:
@@ -170,7 +151,7 @@ def __init__(self, document, meta=None):
170151
self._setup_document_fields()
171152
# Setup self.pk if the document has an id_field in it's meta
172153
# if it doesn't have one it's an embedded document
173-
#if 'id_field' in self._meta:
154+
# if 'id_field' in self._meta:
174155
# self.pk_name = self._meta['id_field']
175156
self._init_pk()
176157

@@ -181,12 +162,23 @@ def _setup_document_fields(self):
181162
if not hasattr(f, 'rel'):
182163
# need a bit more for actual reference fields here
183164
if isinstance(f, ReferenceField):
165+
# FIXME: Probably broken in Django 1.7
184166
f.rel = Relation(f.document_type)
185-
elif isinstance(f, ListField) and \
186-
isinstance(f.field, ReferenceField):
167+
f.is_relation = True
168+
elif isinstance(f, ListField) and isinstance(f.field, ReferenceField):
169+
# FIXME: Probably broken in Django 1.7
187170
f.field.rel = Relation(f.field.document_type)
171+
f.field.is_relation = True
188172
else:
173+
f.many_to_many = None
174+
f.many_to_one = None
175+
f.one_to_many = None
176+
f.one_to_one = None
177+
f.related_model = None
178+
179+
# FIXME: No longer used in Django 1.7?
189180
f.rel = None
181+
f.is_relation = False
190182
if not hasattr(f, 'verbose_name') or f.verbose_name is None:
191183
f.verbose_name = capfirst(create_verbose_name(f.name))
192184
if not hasattr(f, 'flatchoices'):
@@ -202,6 +194,8 @@ def _setup_document_fields(self):
202194
isinstance(f.document_type._meta, (DocumentMetaWrapper, LazyDocumentMetaWrapper)) and \
203195
self.document != f.document_type:
204196
f.document_type._meta = LazyDocumentMetaWrapper(f.document_type)
197+
if not hasattr(f, 'auto_created'):
198+
f.auto_created = False
205199

206200
def _init_pk(self):
207201
"""
@@ -217,58 +211,51 @@ def _init_pk(self):
217211
pk_field = None
218212
self.pk = PkWrapper(pk_field)
219213

220-
def _get_pk_val(self):
221-
return self._pk_val
214+
def _get_pk_val(obj):
215+
return obj.pk
216+
patch_document(_get_pk_val, self.document, False) # document is a class...
222217

223218
if pk_field is not None:
224219
self.pk.name = self.pk_name
225220
self.pk.attname = self.pk_name
226-
self.document._pk_val = pk_field
227-
patch_document(_get_pk_val, self.document)
228221
else:
229222
self.pk.fake = True
230223
# this is used in the admin and used to determine if the admin
231224
# needs to add a hidden pk field. It does not for embedded fields.
232225
# So we pretend to have an editable pk field and just ignore it otherwise
233226
self.pk.editable = True
234-
227+
235228
@property
236229
def app_label(self):
237230
if self._app_label is None:
238-
model_module = sys.modules[self.document.__module__]
239-
# TODO: test it.
240-
self._app_label = model_module.__name__.split('.')[0]
231+
if self._meta.get('app_label'):
232+
self._app_label = self._meta["app_label"]
233+
else:
234+
model_module = sys.modules[self.document.__module__]
235+
self._app_label = model_module.__name__.split('.')[-2]
241236
return self._app_label
242237

243-
@property
244-
def app_config(self):
245-
if self._app_config is None:
246-
from django.apps import apps
247-
self._app_config = apps.get_app_config(self.app_label)
248-
# self._meta['app_config'] = self._app_config
249-
return self._app_config
250-
251238
@property
252239
def verbose_name(self):
253240
"""
254241
Returns the verbose name of the document.
255-
242+
256243
Checks the original meta dict first. If it is not found
257244
then generates a verbose name from the object name.
258245
"""
259246
if self._verbose_name is None:
260247
verbose_name = self._meta.get('verbose_name', self.object_name)
261248
self._verbose_name = capfirst(create_verbose_name(verbose_name))
262249
return self._verbose_name
263-
250+
264251
@property
265252
def verbose_name_raw(self):
266253
return self.verbose_name
267-
254+
268255
@property
269256
def verbose_name_plural(self):
270257
return "%ss" % self.verbose_name
271-
258+
272259
def get_add_permission(self):
273260
return 'add_%s' % self.object_name.lower()
274261

@@ -277,10 +264,10 @@ def get_change_permission(self):
277264

278265
def get_delete_permission(self):
279266
return 'delete_%s' % self.object_name.lower()
280-
267+
281268
def get_ordered_objects(self):
282269
return []
283-
270+
284271
def get_field_by_name(self, name):
285272
"""
286273
Returns the (field_object, model, direct, m2m), where field_object is
@@ -300,13 +287,16 @@ def get_field_by_name(self, name):
300287
else:
301288
raise FieldDoesNotExist('%s has no field named %r' %
302289
(self.object_name, name))
303-
290+
304291
def get_field(self, name, many_to_many=True):
305292
"""
306293
Returns the requested field by name. Raises FieldDoesNotExist on error.
307294
"""
308295
return self.get_field_by_name(name)[0]
309-
296+
297+
def get_fields(self, include_hidden=False):
298+
return self.document._fields.values()
299+
310300
@property
311301
def swapped(self):
312302
"""
@@ -315,7 +305,7 @@ def swapped(self):
315305
316306
For historical reasons, model name lookups using get_model() are
317307
case insensitive, so we make sure we are case insensitive here.
318-
308+
319309
NOTE: Not sure this is actually usefull for documents. So at the
320310
moment it's really only here because the admin wants it. It might
321311
prove usefull for someone though, so it's more then just a dummy.
@@ -337,31 +327,28 @@ def swapped(self):
337327
not in (None, model_label):
338328
return swapped_for
339329
return None
340-
330+
341331
def __getattr__(self, name):
342332
if name in self._deprecated_attrs:
343333
return getattr(self, self._deprecated_attrs.get(name))
344-
334+
345335
try:
346-
# TODO: check it. It seems that is needed return empty string instead of an error.
347-
# print "####### REAL META"
348-
# print self._meta
349336
return self._meta[name]
350337
except KeyError:
351-
return ''
352-
338+
raise AttributeError
339+
353340
def __setattr__(self, name, value):
354341
if not hasattr(self, name):
355342
self._meta[name] = value
356343
else:
357344
super(DocumentMetaWrapper, self).__setattr__(name, value)
358-
345+
359346
def __contains__(self, key):
360347
return key in self._meta
361-
348+
362349
def __getitem__(self, key):
363350
return self._meta[key]
364-
351+
365352
def __setitem__(self, key, value):
366353
self._meta[key] = value
367354

@@ -374,15 +361,21 @@ def __iter__(self):
374361
def __len__(self):
375362
return self._meta.__len__()
376363

364+
def __cmp__(self, other):
365+
return hash(self) == hash(other)
366+
367+
def __hash__(self):
368+
return id(self)
369+
377370
def get(self, key, default=None):
378371
try:
379372
return self.__getitem__(key)
380373
except KeyError:
381374
return default
382-
375+
383376
def get_parent_list(self):
384377
return []
385-
378+
386379
def get_all_related_objects(self, *args, **kwargs):
387380
return []
388381

0 commit comments

Comments
 (0)