title: A custom field inheriting from ForeignKey throws an exception on save
body: <p>I have written the following custom field:</p>
  
  <pre><code>from django.core.urlresolvers import reverse
  from django.db import models
  from django.db.models import signals
  from sitetree.models import Tree, TreeItem
  from south.modelsinspector import introspector
  
  class AutoTreeItemField(models.ForeignKey):
      def __init__(self, *args, **kwargs):
          super(AutoTreeItemField, self).__init__(TreeItem, null=True)
  
          self.date_field = kwargs['date_field']
          self.__should_appear = kwargs['should_appear']
          self.year_menu_item_url = kwargs['year_menu_item_url']
          self.month_menu_item_url = kwargs['month_menu_item_url']
          self.item_menu_item_url = kwargs['item_menu_item_url']
  
          self.year_format = kwargs.get('year_format', '%Y')
          self.month_format = kwargs.get('month_format', '%B')
          self.inmenu = kwargs.get('inmenu', True)
          self.inbreadcrumbs = kwargs.get('inbreadcrumbs', True)
          self.insitetree = kwargs.get('insitetree', True)
          self.item_title = kwargs.get('title', 'title')
  
      def contribute_to_class(self, cls, name):
          super(AutoTreeItemField, self).contribute_to_class(cls, name)
  
          # Make this object the descriptor for field access.
          setattr(cls, self.name, self)
  
          self.tree = self.__get_or_create_tree(cls._meta.verbose_name_plural.lower())
  
          # Delete menu item after the instance is deleted
          signals.post_delete.connect(self.__delete, cls, True)
  
      def pre_save(self, model_instance, add):
          super(AutoTreeItemField, self).pre_save(model_instance, add)
          if self.should_appear(model_instance):
              year_menu_item = self.__get_or_create_year_tree_item(model_instance)
              month_menu_item = self.__get_or_create_month_tree_item(model_instance, year_menu_item)
              menu_item = self.__save_menu_item(model_instance, month_menu_item)
              setattr(model_instance, self.get_attname(), menu_item.id)
  
              return menu_item.id
          else:
              self.__delete_orphans(model_instance)
  
              return None
  
      def __delete(self, **kwargs):
          self.__delete_orphans(kwargs['instace'])
  
      def __get_or_create_tree(self, alias):
          try:
              return Tree.objects.get(alias=alias)
          except Tree.DoesNotExist:
              return Tree.objects.create(alias=alias)
  
      def should_appear(self, instance):
          if isinstance(self.__should_appear, str):
              return getattr(instance, self.__should_appear)
          elif callable(self.__should_appear):
              return self.__should_appear()
  
      def south_field_triple(self):
          """Returns a suitable description of this field for South."""
          args, kwargs = introspector(self)
          kwargs.update({'date_field': 'None'})
          return ('website.blog.fields.AutoTreeItemField', args, kwargs)
  
      def __get_or_create_year_tree_item(self, model_instance):
          year = self.__get_year(model_instance)
  
          try:
              return TreeItem.objects.get(title=year, tree=self.tree)
          except TreeItem.DoesNotExist:
              return TreeItem.objects.create(title=year,
                                             url=reverse(self.year_menu_item_url, args = [year]),
                                             tree=self.tree,
                                             inmenu=self.inmenu,
                                             inbreadcrumbs=self.inbreadcrumbs,
                                             insitetree=self.insitetree,
                                             parent=None)
  
      def __get_year(self, model_instance):
          return getattr(model_instance, self.date_field).strftime(self.year_format)
  
      def __get_or_create_month_tree_item(self, model_instance, year_menu_item):
          month = self.__get_month(model_instance)
  
          try:
              return TreeItem.objects.get(title=month, tree=self.tree, parent=year_menu_item)
          except TreeItem.DoesNotExist:
              return TreeItem.objects.create(title=month,
                                             url=reverse(self.month_menu_item_url, args = [getattr(model_instance, self.date_field).year, getattr(model_instance, self.date_field).month]),
                                             tree=self.tree,
                                             inmenu=self.inmenu,
                                             inbreadcrumbs=self.inbreadcrumbs,
                                             insitetree=self.insitetree,
                                             parent=year_menu_item)
  
      def __get_month(self, model_instance):
          return getattr(model_instance, self.date_field).strftime(self.month_format)
  
      def __save_menu_item(self, model_instance, month_tree_item):
          try:
              item = self.__get_menu_item(model_instance)
  
              item.title = getattr(model_instance, self.item_title)
              item.url = model_instance.get_absolute_url()
              item.parent = month_tree_item
  
              return item
          except TreeItem.DoesNotExist:
              return TreeItem.objects.create(title=getattr(model_instance, self.item_title),
                                             url=model_instance.get_absolute_url(),
                                             tree=self.tree,
                                             inmenu=self.inmenu,
                                             inbreadcrumbs=self.inbreadcrumbs,
                                             insitetree=self.insitetree,
                                             parent=month_tree_item)
  
      def __get_year_tree_item(self, model_instance):
          year = self.__get_year(model_instance)
  
          return TreeItem.objects.filter(title=year, tree=self.tree)
  
      def __delete_orphans(self, model_instance):
          menu_item = self.__get_menu_item(model_instance)
  
          try:
              if menu_item is not None:
                  month_menu_item = menu_item.parent
                  menu_item.delete()
  
                  if TreeItem.objects.filter(parent=month_menu_item, parent__parent=self.__get_year_tree_item(model_instance), tree=self.tree).count():
                          year_menu_item = month_menu_item.parent
  
                          month_menu_item.delete()
  
                          if TreeItem.objects.filter(parent=year_menu_item, tree=self.tree).count() == 0:
                              year_menu_item.delete()
          except TreeItem.DoesNotExist:
              pass
  
      def __get_menu_item(self, model_instance):
          menu_item_id = getattr(model_instance, self.get_attname())
          return TreeItem.objects.get(id=menu_item_id)
  </code></pre>
  
  <p>But when I'm attempting to save it I am getting:  </p>
  
  <pre><code>'AutoTreeItemField' object has no attribute '_meta'
  </code></pre>
  
  <p>Here's the full stacktrace:  </p>
  
  <pre><code>Environment:
  
  
  Request Method: POST
  Request URL: http://127.0.0.1:8000/admin/blog/draftpost/add/
  
  Django Version: 1.3
  Python Version: 2.7.1
  Installed Applications:
  ['django.contrib.auth',
   'django.contrib.contenttypes',
   'django.contrib.sessions',
   'django.contrib.sites',
   'django.contrib.messages',
   'django.contrib.staticfiles',
   'django.contrib.admin',
   'django.contrib.sites',
   'django.contrib.flatpages',
   'tagging',
   'reversion',
   'south',
   'sitetree',
   'dojango',
   'disqus',
   'website.blog',
   'website.cms']
  Installed Middleware:
  ('django.middleware.common.CommonMiddleware',
   'django.contrib.sessions.middleware.SessionMiddleware',
   'django.middleware.csrf.CsrfViewMiddleware',
   'django.contrib.auth.middleware.AuthenticationMiddleware',
   'django.contrib.messages.middleware.MessageMiddleware',
   'dojango.middleware.DojoCollector',
   'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware')
  
  
  Traceback:
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
    111.                         response = callback(request, *callback_args, **callback_kwargs)
  File "C:\Python27\lib\site-packages\django\contrib\admin\options.py" in wrapper
    307.                 return self.admin_site.admin_view(view)(*args, **kwargs)
  File "C:\Python27\lib\site-packages\django\utils\decorators.py" in _wrapped_view
    93.                     response = view_func(request, *args, **kwargs)
  File "C:\Python27\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
    79.         response = view_func(request, *args, **kwargs)
  File "C:\Python27\lib\site-packages\django\contrib\admin\sites.py" in inner
    197.             return view(request, *args, **kwargs)
  File "C:\Python27\lib\site-packages\django\db\transaction.py" in inner
    217.                 res = func(*args, **kwargs)
  File "C:\Python27\lib\site-packages\reversion\revisions.py" in _create_on_success
    352.                 self.end()
  File "C:\Python27\lib\site-packages\reversion\revisions.py" in end
    274.                     revision_set = self.follow_relationships(models)
  File "C:\Python27\lib\site-packages\reversion\revisions.py" in follow_relationships
    244.         map(_follow_relationships, object_dict)
  File "C:\Python27\lib\site-packages\reversion\revisions.py" in _follow_relationships
    243.                     _follow_relationships(parent_obj)
  File "C:\Python27\lib\site-packages\reversion\revisions.py" in _follow_relationships
    213.             result_dict[obj] = self.get_version_data(obj, VERSION_CHANGE)
  File "C:\Python27\lib\site-packages\reversion\revisions.py" in get_version_data
    254.         serialized_data = serializers.serialize(registration_info.format, [obj], fields=registration_info.fields)
  File "C:\Python27\lib\site-packages\django\core\serializers\__init__.py" in serialize
    91.     s.serialize(queryset, **options)
  File "C:\Python27\lib\site-packages\django\core\serializers\base.py" in serialize
    48.                             self.handle_fk_field(obj, field)
  File "C:\Python27\lib\site-packages\django\core\serializers\python.py" in handle_fk_field
    53.                 if field.rel.field_name == related._meta.pk.name:
  
  Exception Type: AttributeError at /admin/blog/draftpost/add/
  Exception Value: 'AutoTreeItemField' object has no attribute '_meta'
  </code></pre>
  
  <p>Can anyone exlpain to me how can this be? What could be done to remedy this issue?<br>
  The wierd thing is that it happens after the transaction ends and it saves everything I need to the database.</p>
  
  <p>EDIT:<br>
  The error is caused by reversion trying to serialize my instance into json. However, this is still my problem because the _meta attribute should have been there and it isn't. How can this be resolved?</p>