src/hdalab/fields.py
author ymh <ymh.work@gmail.com>
Thu, 26 Feb 2015 10:33:10 +0100
changeset 458 604b887e70c3
parent 359 46ad324f6fe4
child 545 c752fdee555b
permissions -rw-r--r--
add state history to renkan, correct get into post, generally prepare ground for mail management

# -*- 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
from south.modelsinspector import add_introspection_rules


class OneToOneField(models.OneToOneField):    
    def __init__(self, to, **kwargs):
        self.related_default = kwargs.pop('related_default', None)
        super(OneToOneField, self).__init__(to, **kwargs)

    def contribute_to_related_class(self, cls, related):
        setattr(cls, related.get_accessor_name(),
                SingleRelatedObjectDescriptor(related, self.related_default))


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
        
add_introspection_rules([
    (
        [OneToOneField],
        [],         # Positional arguments (not used)
        {           # Keyword argument
            "related_default": ["related_default", {"default": None, "is_django_function": True}],
        },
    ),
], ["^hdalab\.fields\.OneToOneField"])