[英]How can I get some of the Django ORM benefits of using a ForeignKey without actually using one?
I have models that look like this (simplified of course): 我有看起来像这样的模型(当然是简化的):
class Product(models.Model):
product_code = Charfield(max_length=30)
class Change(models.Model):
product = ForeignKey(Product)
My problem is that this won't work, because Products get deleted, but I need the reference in Change to remain (using on.delete to set it to null is not an option). 我的问题是,这将不起作用,因为产品被删除了,但是我需要保留Change中的引用(不能使用on.delete将其设置为null)。 So I have switched it to: 所以我将其切换为:
class Change(models.Model):
product = CharField(max_length=30)
But now I have lost the benefits of a Foreign Key field when querying. 但是现在我在查询时失去了外键字段的好处。 When I query for a change, I cannot select_related for Products or do any other join type action without digging into extra
type clauses. 当我查询更改时,如果不深入研究extra
类型子句,就无法为Products选择select_related或执行任何其他联接类型操作。
So my question, is there any good way to have my cake and eat it too? 所以我的问题是,有什么好方法可以吃我的蛋糕吗? To be able to join on the field easily, but not have it be an FK? 能够轻松加入该领域,但又不是FK吗? Seems like there must be some way besides FK type to say that fields are related. 似乎除了FK类型外,还必须有其他方法来说明字段是相关的。 Perhaps through a manager? 也许通过经理?
I have this exact problem at hand... regrettably its priory was bumped pretty far down my list. 我手头有这个确切的问题。。。遗憾的是,它的优先顺序被大大降低了。 However, I believe I have actually used a many-to-many field to retain a link in a different part of my application. 但是,我相信我实际上已经使用了一个多对多字段来在应用程序的不同部分中保留链接。 Using the many-to-many field seems to address all of the issues I had come across. 使用多对多字段似乎可以解决我遇到的所有问题。 See my simplified models below. 请参阅下面的简化模型。
With this setup I am able to: 通过此设置,我可以:
Card Model 卡型号
class Card(models.Model):
serial_number = models.CharField(max_length=25)
card_tests = models.ManyToManyField('Card_Test', through='Card_Test_List')
Through Model 通过模型
class Card_Test_List(models.Model):
card_id = models.ForeignKey('Card')
card_test_id = models.ForeignKey('Card_Test')
result = models.TextField()
Card Test Model 卡测试模型
class Card_Test(models.Model):
name = models.TextField(max_length=100)
description = models.TextField(max_length=200)
You could add a boolean flag deleted
to the Product
model. 你可以添加一个布尔标志deleted
的Product
型号。 When you wish to 'delete' a product, set product.deleted=True
instead of deleting from the database. 当您希望“删除”产品时,请设置product.deleted=True
而不是从数据库中删除。 That would allow you to use a regular foreign key from Change
to Product
. 这将使您可以使用Change
to Product
的常规外键。
I don't know whether this would be suitable for your project. 我不知道这是否适合您的项目。 You might have to change quite a lot of code, eg replace Product.objects.all()
with Product.objects.exclude(deleted=True)
. 您可能必须更改很多代码,例如,将Product.objects.all()
替换为Product.objects.exclude(deleted=True)
。 Creating a manager where the queryset returns non-deleted items would help. 在查询集返回未删除项目的地方创建管理器会有所帮助。
class Product(models.Model):
product_code = Charfield(max_length=30)
deleted = BooleanField(blank=True, null=True)
class Change(models.Model):
product = ForeignKey(Product)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.