Django中父模型对象能否通过OneToOneField使用_set属性?
Django 中 OneToOneField 无法使用 _set 属性的原因
我定义了如下的Person模型和关联OneToOneField的PersonDetail模型:
class Person(models.Model): name = models.CharField(max_length=20) class PersonDetail(models.Model): person = models.OneToOneField(Person, on_delete=models.CASCADE) age = models.IntegerField() gender = models.CharField(max_length=20)
但当我尝试调用Person对象的persondetail_set属性时:
obj = Person.objects.get(id=1) print(obj.persondetail_set.get(id=1)) # ↑ ↑ ↑ 此处 ↑ ↑ ↑
出现了如下错误:
AttributeError: 'Person' object has no attribute 'persondetail_set'
当我将关联字段改为ForeignKey时:
class PersonDetail(models.Model): person = models.ForeignKey(Person, on_delete=models.CASCADE) # ...
则没有报错,输出:
PersonDetail object (1)
改为ManyToManyField时同样无报错:
class PersonDetail(models.Model): person = models.ManyToManyField(Person) # ...
输出:
PersonDetail object (1)
请问在Django中,父模型对象无法通过OneToOneField使用_set属性吗?
是的,OneToOneField 不会为反向关联生成_set后缀的属性。
原因很简单:OneToOneField 是一对一的关联关系,一个Person对象最多只能对应一个PersonDetail对象,不存在“集合”的概念。因此Django直接使用关联模型的小写名称(即persondetail)作为反向关联的属性名,你可以直接这样调用:
obj = Person.objects.get(id=1) print(obj.persondetail) # 直接获取对应的PersonDetail对象
而ForeignKey是一对多关联、ManyToManyField是多对多关联,一个Person可以对应多个PersonDetail对象,所以Django会生成_set后缀的属性来表示这个“集合”,方便你查询关联的多个对象。
如果需要自定义反向关联的属性名,可以在OneToOneField中设置related_name参数,比如:
class PersonDetail(models.Model): person = models.OneToOneField(Person, on_delete=models.CASCADE, related_name='detail') # ...
之后就可以通过obj.detail来访问关联的PersonDetail对象。
内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito
相关产品推荐
相关产品推荐

