如何在不实际使用ForeignKey的情况下获得使用ForeignKey的一些Django ORM好处?

时间:2011-08-31 06:33:57

标签: django orm

我的模型看起来像这样(当然简化):

class Product(models.Model):
    product_code = Charfield(max_length=30)

class Change(models.Model):
    product = ForeignKey(Product)

我的问题是这不起作用,因为产品被删除了,但我需要保留Change中的引用(使用on.delete将其设置为null不是一个选项)。所以我把它换成了:

class Change(models.Model):
    product = CharField(max_length=30)

但是现在我在查询时失去了外键字段的好处。当我查询更改时,我无法选择产品的相关内容或执行任何其他连接类型操作而无需深入查看extra类型子句。

所以我的问题是,有没有什么好方法可以吃我的蛋糕呢?能够轻松加入这个领域,但不是FK吗?似乎除了FK类型之外必须有某种方式来表示字段是相关的。也许是通过经理?

2 个答案:

答案 0 :(得分:0)

我手边有这个确切的问题......遗憾的是它的小修道院在我的名单上被撞了很远。但是,我相信我实际上使用了多对多字段来保留应用程序不同部分的链接。使用多对多字段似乎解决了我遇到的所有问题。请参阅下面的简化模型。

通过此设置,我能够:

  • 创建一张卡并将多个Card_Tests链接到它(注意可能有重复)
  • 修改或删除任何一个或所有Card_Tests,而不删除卡的记录。
  • 删除卡记录,删除所有Card_Tests。

卡片型号

class Card(models.Model):
    serial_number = models.CharField(max_length=25)
    card_tests = models.ManyToManyField('Card_Test', through='Card_Test_List')

通过模型

class Card_Test_List(models.Model):
    card_id = models.ForeignKey('Card')
    card_test_id = models.ForeignKey('Card_Test')
    result       = models.TextField()

卡片测试模型

class Card_Test(models.Model):
    name = models.TextField(max_length=100)
    description = models.TextField(max_length=200)

答案 1 :(得分:0)

您可以向deleted模型添加布尔标记Product。如果您要“删除”某个产品,请设置product.deleted=True而不是从数据库中删除。这样您就可以使用从ChangeProduct的常规外键。

我不知道这是否适合您的项目。您可能需要更改相当多的代码,例如将Product.objects.all()替换为Product.objects.exclude(deleted=True)。创建一个查询集返回未删除项的管理器会有所帮助。

class Product(models.Model):
    product_code = Charfield(max_length=30)
    deleted = BooleanField(blank=True, null=True)

class Change(models.Model):
    product = ForeignKey(Product)