【问题标题】:Django model ForeignKey backwards referencing and AttributeError when trying to use ManyToManyField尝试使用 ManyToManyField 时 Django 模型 ForeignKey 向后引用和 AttributeError
【发布时间】:2018-05-20 07:25:46
【问题描述】:

因此,我正在尝试为读取具有给定数据格式的 .xml 文件的数据库构建模型,但在设置向后兼容性时遇到了麻烦。

我的模特是

from django.db import models

class Continent(models.Model):
    name = models.CharField(max_length=60, default='', unique=True)
    code = models.CharField(max_length=3, default='')


    countries = models.ManyToManyField(
        'Continent',
        through='Country',
    )


class Country(models.Model):

    name = models.CharField(max_length=60, default='', unique=True)
    code = models.CharField(max_length=3, default='', unique=True)
    capital = models.CharField(max_length=60, default='')
    population = models.PositiveIntegerField(default=0)
    area = models.PositiveIntegerField(default=0)
    continent = models.ForeignKey(Continent, default='', related_name='related_name')

如您所见,我对related_name 有点不知所措。无论如何,运行一个解析过这些数据的测试会给我错误

AttributeError: 'ManyToManyField' 对象没有属性 '_m2m_reverse_name_cache'

但我不确定我应该如何消除它。

测试尝试运行

fi = europe.countries.get(code="fi")

如果找不到任何东西(数据包含每个大陆和国家),则会引发异常,因此向后引用目前还不起作用。

编辑: 这是引发异常的测试部分

def testCountryThroughContinent(self):

        europe = Continent.objects.get(code="eu")
        try:
             sw = europe.countries.get(code="sw")
        except:
             self.assertTrue(False, "Getting country failed. Did you remember that countries should be accessed through attribute countries?")
        self.assertEqual(sw.name, "Sweden", "Getting a country from a continent")

【问题讨论】:

  • 您在现实生活中真正想要实现的目标是什么?鉴于名称,您的方法看起来过于复杂
  • 在这个阶段,我正在尝试为数据库制作模型,并且已经为我提供了一个预制的测试功能,以确保它可以正常工作。我现在只有一部分葡萄干异常,我将其编辑到问题中

标签: python django


【解决方案1】:

如果您从国家/地区使用 FK 到大陆,则不需要额外的 M2M

from django.db import models

class Continent(models.Model):
    name = models.CharField(max_length=60, default='', unique=True)
    code = models.CharField(max_length=3, default='')

class Country(models.Model):
    name = models.CharField(max_length=60, default='', unique=True)
    code = models.CharField(max_length=3, default='', unique=True)
    capital = models.CharField(max_length=60, default='')
    population = models.PositiveIntegerField(default=0)
    area = models.PositiveIntegerField(default=0)
    continent = models.ForeignKey(Continent, related_name='countries')

别忘了做makemigrations 然后应用它们

【讨论】:

  • 我需要 Continent 类具有属性“国家”,但是,大陆内的国家/地区将通过代码存储
  • @Grak 是的,我明白这一点,这是通过在您已经完成的 Country 模型中添加 ForeignKey 来实现的。如果你使用这个模型,你可以做fi = europe.countries.get(code="fi")
  • 啊,我明白了,为了让 Continent 类获得属性,related_name 必须是“国家”。谢谢! (之前没注意改名)
猜你喜欢
  • 1970-01-01
  • 2020-06-11
  • 1970-01-01
  • 2013-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-26
  • 2020-05-11
相关资源
最近更新 更多