【发布时间】:2018-05-07 21:03:59
【问题描述】:
我需要在两个模型之间创建多对多关系。在 Django 中,您通常会将 ManyToManyField 添加到两个模型之一。然而,就我而言:
- 这两个模型来自第 3 方库,分别是
User和Car - 两者都不是抽象的,我想避免,例如,多表继承的复杂性只是添加一个 M2M 字段(这实际上不需要任何一个表中的额外列)
- 我正在假设其他人会像(如果不是字面上那样)使用它作为 3rd 方库,所以我真的希望提供标准接口,尽管有限制。
显然,我可以创建一个“手动”M2M 表:
class UserCar(models.Model):
user = models.ForeignKey(User)
car = models.ForeignKey(Car)
class Meta:
unique_together = ('user', 'car')
...但 Django 会将两个 ForeignKey 字段视为多对一,因此标准的“魔术”访问器将不可用:
user.cars.add(car)
car in user.cars
User.objects.filter(cars=car)
有没有一种简单的方法可以在关系双方注入通常的 M2M 魔法? UserCar 基本上是一个 through= 表。我可以创建一个虚拟字段并调用一两个方法(例如contribute_to_class 和contribute_to_related_class)来完成这项工作吗?我尝试通过ForeignKey 和ManyToMany 来解惑,但我对正常的字段级处理不够熟悉,甚至无法猜测关键方法(更不用说排序和延迟处理)。
【问题讨论】:
-
您可以尝试使用
User.add_to_class('cars', models.ManyToManyField(....)),但我对此不确定。它可能会抱怨迁移,如果这是第三方软件包,我不确定接下来会发生什么。也许它会创建对该包的新迁移)。不管怎样,给它一个机会。 P.S. 它也会调用你提到的contribute_to_class。 -
我一定会试一试的。 “直通”模型应该以任何一种方式创建......要么它被选为直通模型,要么它不是,它只是一个自己创建的一等公民。
-
是的,我明白。但是,即使使用 through 表添加 ManyToManyField 时,django 仍会创建迁移以跟踪迁移历史记录中的该字段,即使这不会更改数据库中的任何内容。我现在不确定,但机会很大)
-
我使用了一个简单的
if not hasattr来防止重复调用add_to_class。它添加了该字段,但迁移是在与Car相同的包中创建的(我将该字段添加到Car),因此它们不会被提交到我的存储库中。 -
嗯。可以在第三方内部创建迁移吗?也许他们是一种只添加相关管理器的方法?也许你应该看看 ManyToManyField.contribute_to_class...
标签: django django-models many-to-many