回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>在我的应用程序中,我对所有模型都使用一个公共<code>Base</code>模型。我遇到了无法用<code>Campus</code>和<code>Hall</code>模型解释的行为:</p>
<pre class="lang-py prettyprint-override"><code>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 ''}"
</code></pre>
<p>在管理控制台上,当我试图删除某个<code>Campus</code>实例时,服务器崩溃。这是(很长)轨迹的一小部分:</p>
<pre><code>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__
...
</code></pre>
<p>起初我认为这是<code>Hall</code>和<code>Campus</code>之间的某种循环指向问题,但情况似乎并非如此(在调试时,我看不到从<code>Campus</code>到<code>Hall</code>的任何指针)。奇怪的是,如果我首先删除所有<code>Hall</code>实例,那么<code>Campus</code>的删除就会顺利进行。<br/>
我正在使用<code>python 3.7</code>和<code>Django 3.0.6</code></p>