| author | ymh <ymh.work@gmail.com> |
| Mon, 26 Oct 2015 19:20:54 +0100 | |
| changeset 660 | 04255afd160e |
| parent 545 | c752fdee555b |
| permissions | -rw-r--r-- |
# -*- coding: utf-8 -*- ''' Created on Nov 14, 2014 from https://gist.github.com/gsakkis/601977 to correct https://code.djangoproject.com/ticket/10227 @author: ymh ''' from django.core.exceptions import ObjectDoesNotExist from django.db import models from django.db.models import fields as django_fields def isalambda(v): LAMBDA = lambda:0 return isinstance(v, type(LAMBDA)) and v.__name__ == LAMBDA.__name__ class OneToOneField(models.OneToOneField): def __init__(self, *args, **kwargs): self.related_default = kwargs.pop('related_default', None) #This is BAD. Did this to avoid more work in Django 1.7 migration #TODO: correct this if self.related_default == "lambda:": self.related_default = lambda instance: None super(OneToOneField, self).__init__(*args, **kwargs) def contribute_to_related_class(self, cls, related): setattr(cls, related.get_accessor_name(), SingleRelatedObjectDescriptor(related, self.related_default)) def deconstruct(self): name, path, args, kwargs = super(OneToOneField, self).deconstruct() if self.related_default is not None: # this is VERY dirty and works only in our application. #TODO: correct this... if isalambda(self.related_default): kwargs['related_default'] = "lambda:" else: kwargs['related_default'] = self.related_default return name, path, args, kwargs class SingleRelatedObjectDescriptor(django_fields.related.SingleRelatedObjectDescriptor): def __init__(self, related, default): super(SingleRelatedObjectDescriptor, self).__init__(related) self.default = default def __get__(self, instance, instance_type=None): try: return super(SingleRelatedObjectDescriptor, self).__get__(instance, instance_type) except ObjectDoesNotExist: if self.default is None: raise value = self.default(instance) setattr(instance, self.cache_name, value) if value is not None: setattr(value, self.related.field.get_cache_name(), instance) return value