Package couchdbkit :: Package schema :: Module properties_proxy
[hide private]
[frames] | no frames]

Source Code for Module couchdbkit.schema.properties_proxy

  1  # -*- coding: utf-8 - 
  2  # 
  3  # This file is part of couchdbkit released under the MIT license.  
  4  # See the NOTICE for more information. 
  5   
  6  """ Meta properties """ 
  7   
  8   
  9  from ..exceptions import BadValueError  
 10   
 11  from .base import DocumentSchema 
 12  from .properties import Property 
 13   
 14  __all__ = ['SchemaProperty', 'SchemaListProperty', 'SchemaDictProperty'] 
 15   
16 -class SchemaProperty(Property):
17 """ Schema property. It allows you add a DocumentSchema instance 18 a member of a Document object. It returns a 19 `schemaDocumentSchema` object. 20 21 Exemple : 22 23 >>> from couchdbkit import * 24 >>> class Blog(DocumentSchema): 25 ... title = StringProperty() 26 ... author = StringProperty(default="me") 27 ... 28 >>> class Entry(Document): 29 ... title = StringProperty() 30 ... body = StringProperty() 31 ... blog = SchemaProperty(Blog()) 32 ... 33 >>> test = Entry() 34 >>> test._doc 35 {'body': None, 'doc_type': 'Entry', 'title': None, 'blog': {'doc_type': 'Blog', 'author': u'me', 'title': None}} 36 >>> test.blog.title = "Mon Blog" 37 >>> test._doc 38 {'body': None, 'doc_type': 'Entry', 'title': None, 'blog': {'doc_type': 'Blog', 'author': u'me', 'title': u'Mon Blog'}} 39 >>> test.blog.title 40 u'Mon Blog' 41 >>> from couchdbkit import Server 42 >>> s = Server() 43 >>> db = s.create_db('couchdbkit_test') 44 >>> Entry._db = db 45 >>> test.save() 46 >>> doc = Entry.objects.get(test.id) 47 >>> doc.blog.title 48 u'Mon Blog' 49 >>> del s['simplecouchdb_test'] 50 51 """ 52
53 - def __init__(self, schema, verbose_name=None, name=None, 54 required=False, validators=None, default=None):
55 56 Property.__init__(self, verbose_name=None, 57 name=None, required=False, validators=None, default=default) 58 59 use_instance = True 60 if isinstance(schema, type): 61 use_instance = False 62 63 elif not isinstance(schema, DocumentSchema): 64 raise TypeError('schema should be a DocumentSchema instance') 65 66 elif schema.__class__.__name__ == 'DocumentSchema': 67 use_instance = False 68 properties = schema._dynamic_properties.copy() 69 schema = DocumentSchema.build(**properties) 70 71 self._use_instance = use_instance 72 self._schema = schema
73
74 - def default_value(self):
75 if not self._use_instance: 76 if self.default: 77 return self.default 78 return self._schema() 79 return self._schema.clone()
80
81 - def empty(self, value):
82 if not hasattr(value, '_doc'): 83 return True 84 if not value._doc or value._doc is None: 85 return True 86 return False
87
88 - def validate(self, value, required=True):
89 value.validate(required=required) 90 value = super(SchemaProperty, self).validate(value) 91 92 if value is None: 93 return value 94 95 if not isinstance(value, DocumentSchema): 96 raise BadValueError( 97 'Property %s must be DocumentSchema instance, not a %s' % (self.name, 98 type(value).__name__)) 99 100 return value
101
102 - def to_python(self, value):
103 if not self._use_instance: 104 schema = self._schema() 105 else: 106 schema = self._schema.clone() 107 108 if not self._use_instance: 109 schema = self._schema 110 else: 111 schema = self._schema.__class__ 112 return schema.wrap(value)
113
114 - def to_json(self, value):
115 if not isinstance(value, DocumentSchema): 116 if not self._use_instance: 117 schema = self._schema() 118 else: 119 schema = self._schema.clone() 120 121 if not isinstance(value, dict): 122 raise BadValueError("%s is not a dict" % str(value)) 123 value = schema(**value) 124 125 return value._doc
126
127 -class SchemaListProperty(Property):
128 """A property that stores a list of things. 129 130 """
131 - def __init__(self, schema, verbose_name=None, default=None, 132 required=False, **kwds):
133 134 Property.__init__(self, verbose_name, default=default, 135 required=required, **kwds) 136 137 use_instance = True 138 if isinstance(schema, type): 139 use_instance = False 140 141 elif not isinstance(schema, DocumentSchema): 142 raise TypeError('schema should be a DocumentSchema instance') 143 144 elif schema.__class__.__name__ == 'DocumentSchema': 145 use_instance = False 146 properties = schema._dynamic_properties.copy() 147 schema = DocumentSchema.build(**properties) 148 149 self._use_instance = use_instance 150 self._schema = schema
151
152 - def validate(self, value, required=True):
153 value = super(SchemaListProperty, self).validate(value, required=required) 154 if value and value is not None: 155 if not isinstance(value, list): 156 raise BadValueError('Property %s must be a list' % self.name) 157 value = self.validate_list_schema(value, required=required) 158 return value
159
160 - def validate_list_schema(self, value, required=True):
161 for v in value: 162 v.validate(required=required) 163 return value
164
165 - def default_value(self):
166 return []
167
168 - def to_python(self, value):
169 return LazySchemaList(value, self._schema, self._use_instance)
170
171 - def to_json(self, value):
172 return [svalue_to_json(v, self._schema, self._use_instance) for v in value]
173 174
175 -class LazySchemaList(list):
176
177 - def __init__(self, doc, schema, use_instance, init_vals=None):
178 list.__init__(self) 179 180 self.schema = schema 181 self.use_instance = use_instance 182 self.doc = doc 183 if init_vals is None: 184 # just wrap the current values 185 self._wrap() 186 else: 187 # initialize this list and the underlying list 188 # with the values given. 189 del self.doc[:] 190 for item in init_vals: 191 self.append(item)
192
193 - def _wrap(self):
194 for v in self.doc: 195 if not self.use_instance: 196 schema = self.schema() 197 else: 198 schema = self.schema.clone() 199 200 value = schema.wrap(v) 201 list.append(self, value)
202
203 - def __delitem__(self, index):
204 del self.doc[index] 205 list.__delitem__(self, index)
206
207 - def __setitem__(self, index, value):
208 self.doc[index] = svalue_to_json(value, self.schema, 209 self.use_instance) 210 list.__setitem__(self, index, value)
211
212 - def __delslice__(self, i, j):
213 del self.doc[i:j] 214 super(LazySchemaList, self).__delslice__(i, j)
215
216 - def __getslice__(self, i, j):
217 return LazySchemaList(self.doc[i:j], self.schema, self.use_instance)
218
219 - def __setslice__(self, i, j, seq):
220 self.doc[i:j] = (svalue_to_json(v, self.schema, self.use_instance) 221 for v in seq) 222 super(LazySchemaList, self).__setslice__(i, j, seq)
223
224 - def __contains__(self, value):
225 for item in self.doc: 226 if item == value._doc: 227 return True 228 return False
229
230 - def append(self, *args, **kwargs):
231 if args: 232 assert len(args) == 1 233 value = args[0] 234 else: 235 value = kwargs 236 237 self.doc.append(svalue_to_json(value, self.schema, 238 self.use_instance)) 239 super(LazySchemaList, self).append(value)
240
241 - def count(self, value):
242 return sum(1 for item in self.doc if item == value._doc)
243
244 - def extend(self, x):
245 self.doc.extend([svalue_to_json(item, self.schema, self.use_instance) 246 for item in x]) 247 super(LazySchemaList, self).extend(x)
248
249 - def index(self, value, *args):
250 try: 251 i = max(0, args[0]) 252 except IndexError: 253 i = 0 254 try: 255 j = min(len(self.doc), args[1]) 256 except IndexError: 257 j = len(self.doc) 258 if j < 0: 259 j += len(self.doc) 260 for idx, item in enumerate(self.doc[i:j]): 261 if item == value._doc: 262 return idx + i 263 else: 264 raise ValueError('list.index(x): x not in list')
265
266 - def insert(self, index, value):
267 self.__setslice__(index, index, [value])
268
269 - def pop(self, index=-1):
270 del self.doc[index] 271 return super(LazySchemaList, self).pop(index)
272
273 - def remove(self, value):
274 try: 275 del self[self.index(value)] 276 except ValueError: 277 raise ValueError('list.remove(x): x not in list')
278
279 - def reverse(self):
280 self.doc.reverse() 281 list.reverse(self)
282
283 - def sort(self, cmp=None, key=None, reverse=False):
284 self.doc.sort(cmp, key, reverse) 285 list.sort(self, cmp, key, reverse)
286 287
288 -class SchemaDictProperty(Property):
289 """A property that stores a dict of things. 290 291 """
292 - def __init__(self, schema, verbose_name=None, default=None, 293 required=False, **kwds):
294 295 Property.__init__(self, verbose_name, default=default, 296 required=required, **kwds) 297 298 use_instance = True 299 if isinstance(schema, type): 300 use_instance = False 301 302 elif not isinstance(schema, DocumentSchema): 303 raise TypeError('schema should be a DocumentSchema instance') 304 305 elif schema.__class__.__name__ == 'DocumentSchema': 306 use_instance = False 307 properties = schema._dynamic_properties.copy() 308 schema = DocumentSchema.build(**properties) 309 310 self._use_instance = use_instance 311 self._schema = schema
312
313 - def validate(self, value, required=True):
314 value = super(SchemaDictProperty, self).validate(value, required=required) 315 if value and value is not None: 316 if not isinstance(value, dict): 317 raise BadValueError('Property %s must be a dict' % self.name) 318 value = self.validate_dict_schema(value, required=required) 319 return value
320
321 - def validate_dict_schema(self, value, required=True):
322 for v in value.values(): 323 v.validate(required=required) 324 return value
325
326 - def default_value(self):
327 return {}
328
329 - def to_python(self, value):
330 return LazySchemaDict(value, self._schema, self._use_instance)
331
332 - def to_json(self, value):
333 return dict([(k, svalue_to_json(v, self._schema, self._use_instance)) for k, v in value.items()])
334 335
336 -class LazySchemaDict(dict):
337
338 - def __init__(self, doc, schema, use_instance, init_vals=None):
339 dict.__init__(self) 340 341 self.schema = schema 342 self.use_instance = use_instance 343 self.doc = doc 344 if init_vals is None: 345 # just wrap the current values 346 self._wrap() 347 else: 348 # initialize this dict and the underlying dict 349 # with the values given. 350 del self.doc[:] 351 for k, v in init_vals: 352 self[k] = self._wrap(v)
353
354 - def _wrap(self):
355 for k, v in self.doc.items(): 356 if not self.use_instance: 357 schema = self.schema() 358 else: 359 schema = self.schema.clone() 360 361 value = schema.wrap(v) 362 dict.__setitem__(self, k, value)
363
364 - def __delitem__(self, index):
365 index = str(index) 366 del self.doc[index] 367 dict.__delitem__(self, index)
368
369 - def __getitem__(self, index):
370 index = str(index) 371 return dict.__getitem__(self, index)
372
373 - def __setitem__(self, index, value):
374 index = str(index) 375 self.doc[index] = svalue_to_json(value, self.schema, 376 self.use_instance) 377 dict.__setitem__(self, index, value)
378 379
380 -def svalue_to_json(value, schema, use_instance):
381 if not isinstance(value, DocumentSchema): 382 if not isinstance(value, dict): 383 raise BadValueError("%s is not a dict" % str(value)) 384 385 if not use_instance: 386 value = schema(**value) 387 else: 388 value = schema.clone(**value) 389 390 return value._doc
391