funkybob  committed 6845ee9

Added defaults handling to AutoOneToOneField

  • Participants
  • Parent commits ea7f660

Comments (0)

Files changed (1)

File gnocchi/tools/

 from django.db.models.fields import related
 from django.db import router
+# XXX Add a way to provide a "build one for me" hook
 class AutoSingleRelatedObjectDescriptor(related.SingleRelatedObjectDescriptor):
+    def __init__(self, related, defaults):
+        self._defaults = defaults or {}
+        super(AutoSingleRelatedObjectDescriptor, self).__init__(related)
     def __get__(self, instance, instance_type=None):
         if instance is None:
             return self
         except AttributeError:
             rel = self.related
             params = {'%s' % instance}
+            defaults = self._defaults or {}
+            if callable(defaults):
+                defaults = defaults(instance)
+            params['defaults'] = self._defaults
             db = router.db_for_read(rel.model, instance=instance)
             rel_obj = rel.model._base_manager.using(db).get_or_create(**params)[0]
             setattr(instance, self.cache_name, rel_obj)
 class AutoOneToOneField(related.OneToOneField):
-    '''A OneToOne field that will create an instance if the target looks us up.'''
+    '''
+    A OneToOne field that will create of the model if the related model follows
+    the reverse relation and it hasn't been created yet.
+    You can pass 'defaults' to specify the new creation defaults to pass to
+    get_or_create.  It should be either a dict, or a callable that accepts one
+    parameter: the instance following the relation.
+    '''
+    def __init__(self, defaults=None, **kwargs):
+        self.defaults = defaults
+        super(AutoOneToOneField, self).__init__(self, **kwargs)
     def contribute_to_related_class(self, cls, related):
         setattr(cls, related.get_accessor_name(),
-            AutoSingleRelatedObjectDescriptor(related)
+            AutoSingleRelatedObjectDescriptor(related, self.defaults)