title: Django AttributeError: type object 'User' has no attribute '_collect_sub_objects'
body: <p>I'm trying to reinstall a site I haven't used in several months and am getting an error I can't seem to find a solution for.  </p>
  
  <p>Running the latest trunk of django, python 2.6.   </p>
  
  <p>Here is the stack trace:::</p>
  
  <pre><code>[Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X] mod_wsgi (pid=9458): Exception occurred processing WSGI script '/home/www/vhosts/site/site.wsgi'.
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X] Traceback (most recent call last):
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/usr/lib/python2.6/site-packages/django/core/handlers/wsgi.py", line 273, in __call__
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     response = self.get_response(request)
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/usr/lib/python2.6/site-packages/django/core/handlers/base.py", line 169, in get_response
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/usr/lib/python2.6/site-packages/django/core/handlers/base.py", line 214, in handle_uncaught_exception
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     if resolver.urlconf_module is None:
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/usr/lib/python2.6/site-packages/django/core/urlresolvers.py", line 274, in _get_urlconf_module
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     self._urlconf_module = import_module(self.urlconf_name)
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/usr/lib/python2.6/site-packages/django/utils/importlib.py", line 35, in import_module
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     __import__(name)
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/home/www/vhosts/site.com/site/urls.py", line 7, in &lt;module&gt;
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     from site.feeds import *
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/home/www/vhosts/site.com/site/feeds.py", line 6, in &lt;module&gt;
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     from site.content.models import *
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/home/www/vhosts/site.com/site/content/models.py", line 14, in &lt;module&gt;
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     from site.authors.models import Author
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/home/www/vhosts/site.com/site/authors/models.py", line 11, in &lt;module&gt;
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     class Author(models.Model):
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/usr/lib/python2.6/site-packages/django/db/models/base.py", line 97, in __new__
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     new_class.add_to_class(obj_name, obj)
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/usr/lib/python2.6/site-packages/django/db/models/base.py", line 217, in add_to_class
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     value.contribute_to_class(cls, name)
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/usr/lib/python2.6/site-packages/django/db/models/fields/related.py", line 891, in contribute_to_class
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     super(ForeignKey, self).contribute_to_class(cls, name)
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/usr/lib/python2.6/site-packages/django/db/models/fields/related.py", line 112, in contribute_to_class
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     self.do_related_class(other, cls)
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/usr/lib/python2.6/site-packages/django/db/models/fields/related.py", line 124, in do_related_class
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     self.contribute_to_related_class(other, self.related)
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]   File "/home/www/vhosts/site.com/site/utils/nullableforeignkey.py", line 38, in contribute_to_related_class
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X]     setattr(cls, _original_csb_attr_name, cls._collect_sub_objects)
  [Fri Apr 01 19:31:00 2011] [error] [client X.X.X.X] **AttributeError: type object 'User' has no attribute '_collect_sub_objects'**
  </code></pre>
  
  <p><strong>Here is the file in question ::</strong></p>
  
  <pre><code>from django.db import models, connection
  
  class NullableForeignKey(models.ForeignKey):
      """
      Just like a ForeignKey, but when related objects are deleted this object is
      *not* deleted. As the name implies, this field is always NULLable.
      """
  
      def __init__(self, *args, **kwargs):
          kwargs['null'] = kwargs['blank'] = True
          super(NullableForeignKey, self).__init__(*args, **kwargs)
  
      def contribute_to_related_class(self, cls, related):
          super(NullableForeignKey, self).contribute_to_related_class(cls, related)
  
          # define a method name to map the original `_collect_sub_objects` method to
          _original_csb_attr_name = '_original_collect_sub_objects'
          this_field = self
  
          def _new_collect_sub_objects(self, *args, **kwargs):
              # NULL out anything related to this object.
              qn = connection.ops.quote_name
              for related in self._meta.get_all_related_objects():
                  if isinstance(related.field, this_field.__class__):
                      table = qn(related.model._meta.db_table)
                      column = qn(related.field.column)
                      sql = "UPDATE %s SET %s = NULL WHERE %s = %%s;" % (table, column, column)
                      connection.cursor().execute(sql, [self.pk])
  
              # Now proceed with collecting sub objects that are still tied via FK
              getattr(self, _original_csb_attr_name)(*args, **kwargs)
  
          # monkey patch the related classes _collect_sub_objects method.
          # store the original method in an attr named `_original_csb_attr_name`
          if not hasattr(cls, _original_csb_attr_name):
              setattr(cls, _original_csb_attr_name, cls._collect_sub_objects)
              setattr(cls, '_collect_sub_objects', _new_collect_sub_objects)
  
  
  # Prevent deletion completely if item has related children
  from django.db.models import OneToOneField, ObjectDoesNotExist
  from django.utils.encoding import StrAndUnicode
  from django.utils.translation import ugettext as _
  
  class ForeignKeysExist(StrAndUnicode, Exception):
      def __init__(self, parent, child, field):
          '''
              Arguments:
              parent - parent instance (that contains child records)
              child  - object that have foreign key pointing to the parent instance
              field  - child instance foreign key field name
          '''
          self.parent = parent #parent instance
          self.child = child #child that has reference to this parent
          self.field = field #field in the child class that points to the parent
          self.msg = 'Child record %s.%s exists for %s' % (_(child), _(field), _(parent))
          super(ForeignKeysExist, self)
  
      def __unicode__(self):
          return self.msg
  
  class NoDeleteCascadeMixin(object):
      """
      Mixin to prevent deletion of model
      if there exists any children
      """
  
      def delete(self):
          # Copied sanity test from django.db.models.ModelBase.delete
          assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname)
  
          opts = self._meta
  
          for related in opts.get_all_related_objects():
              rel_accessor = related.get_accessor_name()
              if isinstance(related, OneToOneField):
                  try:
                      o = getattr(self, rel_accessor)
                  except ObjectDoesNotExist:
                      pass # No item in one to one
                  else:
                      raise ForeignKeysExist(related.parent_model._meta.object_name, opts.object_name, related.field.name)
              else:
                  rel_manager = getattr(self, rel_accessor)
                  if rel_manager.count():
                      raise ForeignKeysExist(related.parent_model._meta.object_name, related.model._meta.object_name, related.field.name)
  
          super(NoDeleteCascadeMixin, self).delete()
  </code></pre>