我现在正在定义我的Django模型,我意识到在模型字段类型中没有OneToManyField。我相信有办法做到这一点,所以我不确定我错过了什么。我基本上有这样的东西:
class Dude(models.Model):
numbers = models.OneToManyField('PhoneNumber')
class PhoneNumber(models.Model):
number = models.CharField()
在这种情况下,每个Dude可以有多个PhoneNumber,但这种关系应该是单向的,因为我不需要从PhoneNumber中知道哪个Dude拥有它,本质上,因为我可能有许多不同的对象拥有PhoneNumber实例,例如Business:
class Business(models.Model):
numbers = models.OneToManyField('PhoneNumber')
我将在模型中用什么替换OneToManyField(它不存在)来表示这种关系?我来自Hibernate/JPA,在那里声明一对多关系非常简单:
@OneToMany
private List<PhoneNumber> phoneNumbers;
如何在Django中表达这一点?
虽然《滚石》杂志的回答很好,直截了当,而且很实用,但我认为有两件事它没有解决。
如果OP想要强制一个电话号码不能同时属于Dude和Business
由于在PhoneNumber模型上定义关系而不是在Dude/Business模型上定义关系而产生的不可避免的悲伤感觉。当外星人来到地球时,我们想要添加一个Alien模型,我们需要修改PhoneNumber(假设外星人有电话号码),而不是简单地向Alien模型添加一个“phone_numbers”字段。
介绍内容类型框架,它公开了一些对象,允许我们在PhoneNumber模型上创建“通用外键”。然后,我们可以在Dude和Business上定义反向关系
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.db import models
class PhoneNumber(models.Model):
number = models.CharField()
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
owner = GenericForeignKey()
class Dude(models.Model):
numbers = GenericRelation(PhoneNumber)
class Business(models.Model):
numbers = GenericRelation(PhoneNumber)
有关详细信息,请参阅文档,也可以查看这篇文章以获得快速教程。
此外,这里有一篇文章反对使用通用fk。
尽管这里的大多数答案在定义关系时传递了允许您定义OneToManyRelationship的关系,但它们实际上是多对多关系的定义。
下面是一个更准确的实现:
class Dude(models.Model):
name = models.CharField(max_length=256, unique=True)
class PhoneNumber(models.Model):
number = models.CharField(max_length=256, unique=True)
class DudePhoneNumbers(models.Model):
dude = models.ForeignKey(Dude, related_name="phone_number_relations", on_delete=models.CASCADE)
phone_number = models.OneToOneField(PhoneNumber, related_name="dude_relation", on_delete=models.CASCADE)