我正在使用django-model-utils程序包,并且试图覆盖在我也为其定义InheritanceManager的模型上的 getattr 。
我有多个继承自同一模型的模型,并且我在父模型上调用.select_subclasses()以获得子模型的查询集。
问题是InheritanceManager在ObjectDoesNotExist异常上进行了try / except,而我的 getattr 引发了AttributeError异常(这是标准的)。这会导致查询集失败,因为InheritanceManager无法捕获AttributeError。
有关如何解决此问题的任何想法。我不认为我想在我的 getattr 方法中引发ObjectDoesNotExist ..但不确定要尝试什么。
谢谢!
models.py:
from django.db import models
from model_utils.managers import InheritanceManager
class Item(models.Model):
name = models.CharField(max_length=32)
description = models.CharField(max_length=100, default='')
objects = InheritanceManager()
def __getattr__(self, name):
raise AttributeError('Attribute {} not found on item {}'.format(name, self.name))
class ItemA(Item):
attribute_a = models.CharField(max_length=10)
class ItemB(Item):
attribute_b = models.CharField(max_length=10)
测试:
if __name__ == "__main__":
# Initialize Django Environment
import os, sys
sys.path.append('C:/Data/Code/quicktest/testproject')
os.environ['DJANGO_SETTINGS_MODULE'] = 'testproject.settings'
import django
django.setup()
from testapp.models import Item
for item in Item.objects.all().select_subclasses():
print(item.name)
结果:
Traceback (most recent call last):
File "C:/Data/Code/quicktest/testproject/testapp/tests.py", line 11, in <module>
for item in Item.objects.all().select_subclasses():
File "C:\Data\Code\quicktest\venv\lib\site-packages\django\db\models\query.py", line 274, in __iter__
self._fetch_all()
File "C:\Data\Code\quicktest\venv\lib\site-packages\django\db\models\query.py", line 1242, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "C:\Data\Code\quicktest\venv\lib\site-packages\model_utils\managers.py", line 28, in __iter__
sub_obj = queryset._get_sub_obj_recurse(obj, s)
File "C:\Data\Code\quicktest\venv\lib\site-packages\model_utils\managers.py", line 211, in _get_sub_obj_recurse
node = getattr(obj, rel)
File "C:\Data\Code\quicktest\testproject\testapp\models.py", line 12, in __getattr__
raise AttributeError('Attribute {} not found on item {}'.format(name, self.name))
AttributeError: Attribute itema not found on item some itemb
答案 0 :(得分:0)
我找到了可行的解决方案。虽然不确定我对此感到兴奋。
def __getattr__(self, name):
# Do magical stuff that getattr is intended for
# Catch if the reason this was called was because its a reverse one to one that doesn't exist
try:
model_field = self.__class__._meta.get_field(name)
if isinstance(model_field, models.fields.reverse_related.OneToOneRel):
return None
except models.fields.FieldDoesNotExist:
pass
raise AttributeError('Attribute {} not found on item {}'.format(name, self.name))
我觉得InheritanceManager应该接受AttributeError异常,但这是可行的