我正在尝试重新安装一个我几个月没用过的网站,并且收到错误,我似乎无法找到解决方案。
运行django的最新主干,python 2.6。
这是堆栈跟踪:::
[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 <module>
[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 <module>
[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 <module>
[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 <module>
[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'**
以下是有问题的文件::
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()
答案 0 :(得分:2)
查看django源代码,_collect_sub_objects
在版本1.2和1.3之间被删除了。请参阅changes
。
Django现在为ForeignKeys docs提供了 on_delete
选项。
<强> ForeignKey.on_delete 强>
删除ForeignKey引用的对象时,Django by 默认模拟的行为 SQL约束ON DELETE CASCADE和 还会删除包含该对象的对象 ForeignKey的。这种行为可以 通过指定on_delete来覆盖 论点。例如,如果你有 可以为空的ForeignKey,你想要它 在引用的对象时设置为null 被删除:
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)
on_delete的可能值是 在django.db.models中找到:
CASCADE:Cascade删除;默认。
PROTECT:通过引发django.db.models.ProtectedError(django.db.IntegrityError的子类)来防止删除引用的对象。
SET_NULL:设置ForeignKey为null;只有当null为True时才可以这样做。
SET_DEFAULT:将ForeignKey设置为其默认值;必须设置ForeignKey的默认值。
SET():将ForeignKey设置为传递给SET()的值,或者如果传入了callable,则调用它的结果。在大多数情况下,为了避免在导入models.py时执行查询,必须传递一个callable:
def get_sentinel_user():
return User.objects.get_or_create(username='deleted')[0]
class MyModel(models.Model):
user = models.ForeignKey(User, on_delete=models.SET(get_sentinel_user))
DO_NOTHING:不采取任何行动。如果数据库后端强制实施参照完整性,除非您手动将SQL ON DELETE约束添加到数据库字段(可能使用初始sql),否则这将导致IntegrityError。