Django:如果相关对象不存在,OneToOneField返回'None'?
我有一个这样的Django类:
class Breakfast(m.Model):
# egg = m.OneToOneField(Egg)
...
class Egg(m.Model):
breakfast = m.OneToOneField(Breakfast, related_name="egg")
如果没有与Breakfast
相关的Egg
,那么breakfast.egg == None
是可能的吗?
编辑:我忘了提:我不想把related_name
改成类似related_name="_egg"
,然后再用这样的方式:
@property
def egg(self):
try:
return self.egg
except ...:
return None
因为我在查询中使用了egg
这个名字,我不想把查询改成用_egg
。
6 个回答
5
我知道在外键(ForeignKey)中,你可以设置 null=True
,这样就允许这个模型不指向其他任何模型。而一对一(OneToOne)其实只是外键的一种特殊情况。
class Place(models.Model)
address = models.CharField(max_length=80)
class Shop(models.Model)
place = models.OneToOneField(Place, null=True)
name = models.CharField(max_length=50)
website = models.URLField()
>>>s1 = Shop.objects.create(name='Shop', website='shop.com')
>>>print s1.place
None
9
我刚遇到这个问题,发现了一个奇怪的解决办法:如果你使用了select_related(),那么如果没有相关的数据行,那个属性会变成None,而不是报错。
>>> print Breakfast.objects.get(pk=1).egg
Traceback (most recent call last):
...
DoesNotExist: Egg matching query does not exist
>>> print Breakfast.objects.select_related("egg").get(pk=1).egg
None
不过我不确定这算不算一个稳定的特性。
12
这个自定义的 Django 字段会完全满足你的需求:
class SingleRelatedObjectDescriptorReturnsNone(SingleRelatedObjectDescriptor):
def __get__(self, *args, **kwargs):
try:
return super(SingleRelatedObjectDescriptorReturnsNone, self).__get__(*args, **kwargs)
except ObjectDoesNotExist:
return None
class OneToOneOrNoneField(models.OneToOneField):
"""A OneToOneField that returns None if the related object doesn't exist"""
related_accessor_class = SingleRelatedObjectDescriptorReturnsNone
使用方法如下:
class Breakfast(models.Model):
pass
# other fields
class Egg(m.Model):
breakfast = OneToOneOrNoneField(Breakfast, related_name="egg")
breakfast = Breakfast()
assert breakfast.egg == None