# -*- 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