Commits

Anonymous committed 60bb4cd

workaround for ForeignKey and OneToOne fields that use a string value for the to arg

  • Participants
  • Parent commits a37594b

Comments (0)

Files changed (2)

File simple_history/fields.py

+from django.db.models import ForeignKey, OneToOneField
+
+class SimpleHistoryForeignKey(ForeignKey):
+    """
+        Allows a ForeignKey to work when
+        'to' is a string
+        
+        Kwarg 'sh_to_field' should be a field instance
+        with the same arguments as the 'to' field.
+    """
+    def __init__(self, *args, **kwargs):
+        sh_to_field = kwargs.pop("sh_to_field",None)
+        if sh_to_field is not None:
+            self.sh_to_field = sh_to_field
+        else:
+            raise ValueError("'sh_to_field' is a required kwarg.")
+        super(SimpleHistoryForeignKey,self).__init__(*args, **kwargs)
+
+class SimpleHistoryOneToOneField(OneToOneField):
+    """
+        Allows a OneToOneField to work when
+        'to' is a string
+        
+        Kwarg 'sh_to_field' should be a field instance
+        with the same arguments as the 'to' field.
+    """
+    def __init__(self, *args, **kwargs):
+        sh_to_field = kwargs.pop("sh_to_field",None)
+        if sh_to_field is not None:
+            self.sh_to_field = sh_to_field
+        else:
+            raise ValueError("'sh_to_field' is a required kwarg.")
+        super(OneToOneField,self).__init__(*args, **kwargs)

File simple_history/models.py

 import copy
 import datetime
 from django.db import models
+from fields import SimpleHistoryForeignKey,SimpleHistoryOneToOneField
 from manager import HistoryDescriptor
 
 class HistoricalRecords(object):
             if isinstance(field, models.ForeignKey):
                 # do not assume that the ForeignKey
                 # points to an AutoField
-                to_field = field.rel.to._meta.get_field(field.rel.field_name)
+                try:
+                    to_field = field.rel.to._meta.get_field(field.rel.field_name)
+                except AttributeError:
+                    try:
+                        to_field = field.sh_to_field
+                    except AttributeError:
+                        if isinstance(field.rel.to,basestring) \
+                        and not isinstance(field,SimpleHistoryForeignKey) \
+                        or not isinstance(field,SimpleHistoryOneToOneField):
+                            raise TypeError("ForeignKey and OneToOne fields with a string 'to' must inherit from SimpleHistoryForeignKey or SimpleHistoryOneToOneField.")
+                        else:
+                            raise
                 if isinstance(to_field, models.AutoField): 
                     field.__class__ = models.IntegerField
                 else: