【发布时间】:2020-06-04 15:36:31
【问题描述】:
在我的应用程序中,我为所有模型使用了一个通用的 Base 模型。我遇到了 Campus 和 Hall 模型无法解释的行为:
class Base(models.Model):
id: int = models.AutoField(primary_key=True, editable=False)
class Meta:
abstract = True
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._initial = self.as_dict
...
@property
def as_dict(self) -> dict:
fields = [field.name for field in self._meta.fields]
res = model_to_dict(self, fields=fields)
return res
...
class Campus(Base):
name: str = models.CharField(max_length=100)
class Meta:
verbose_name_plural = "campuses"
def __str__(self):
return self.name
class Hall(Base):
name: str = models.CharField(max_length=100)
campus: Campus = models.ForeignKey(Campus, on_delete=models.SET_NULL, null=True)
def save(self, *args, **kwargs):
if self.campus is not None and isinstance(self.campus, str):
self.campus = Campus.objects.get_or_create(name=self.campus)[0]
super().save(*args, **kwargs)
def __str__(self):
return f"{self.name}{f' ({self.campus})' if self.campus else ''}"
在管理控制台上,当我尝试删除某个 Campus 实例时,服务器崩溃了。这是(非常长的)跟踪的一小部分:
Fatal Python error: Cannot recover from stack overflow.
...
Current thread 0x00000bdc (most recent call first):
...
File "P:\Python\Coursist\academic_helper\models\base.py", line 142 in as_dict
File "P:\Python\Coursist\academic_helper\models\base.py", line 98 in __init__
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\base.py", line 512 in from_db
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\query.py", line 75 in __iter__
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\query.py", line 1261 in _fetch_all
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\query.py", line 258 in __len__
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\query.py", line 411 in get
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\base.py", line 627 in refresh_from_db
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\query_utils.py", line 139 in __get__
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\fields\__init__.py", line 931 in value_from_object
File "C:\Venvs\Coursist\lib\site-packages\django\forms\models.py", line 93 in model_to_dict
File "P:\Python\Coursist\academic_helper\models\base.py", line 142 in as_dict
File "P:\Python\Coursist\academic_helper\models\base.py", line 98 in __init__
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\base.py", line 512 in from_db
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\query.py", line 75 in __iter__
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\query.py", line 1261 in _fetch_all
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\query.py", line 258 in __len__
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\query.py", line 411 in get
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\base.py", line 627 in refresh_from_db
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\query_utils.py", line 139 in __get__
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\fields\__init__.py", line 931 in value_from_object
File "C:\Venvs\Coursist\lib\site-packages\django\forms\models.py", line 93 in model_to_dict
File "P:\Python\Coursist\academic_helper\models\base.py", line 142 in as_dict
File "P:\Python\Coursist\academic_helper\models\base.py", line 98 in __init__
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\base.py", line 512 in from_db
File "C:\Venvs\Coursist\lib\site-packages\django\db\models\query.py", line 75 in __iter__
...
起初我认为这是Hall 和Campus 之间的某种循环指向问题,但似乎并非如此(调试时,我看不到Campus 指向的任何指针Hall)。奇怪的是,如果我先删除所有Hall 实例,Campus 的删除会顺利进行。
我正在使用python 3.7 和Django 3.0.6
【问题讨论】:
标签: python django python-3.x django-models stack-overflow