Dav*_*ver 21 python django django-models
我有一个像这样的Django类:
class Breakfast(m.Model):
# egg = m.OneToOneField(Egg)
...
class Egg(m.Model):
breakfast = m.OneToOneField(Breakfast, related_name="egg")
Run Code Online (Sandbox Code Playgroud)
是否有可能有breakfast.egg == None,如果没有Egg相关的Breakfast?
编辑:忘记提及:我宁愿不改变related_name类似的东西related_name="_egg",然后有类似的东西:
@property
def egg(self):
try:
return self.egg
except ...:
return None
Run Code Online (Sandbox Code Playgroud)
因为我egg在查询中使用该名称,我宁愿不必将查询更改为使用_egg.
我刚遇到这个问题,并找到了一个奇怪的解决方案:如果你selectRelated(),那么如果不存在相关行,该属性将为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
Run Code Online (Sandbox Code Playgroud)
我不知道这是否可以被认为是一个稳定的功能.
这个自定义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
Run Code Online (Sandbox Code Playgroud)
要使用它:
class Breakfast(models.Model):
pass
# other fields
class Egg(m.Model):
breakfast = OneToOneOrNoneField(Breakfast, related_name="egg")
breakfast = Breakfast()
assert breakfast.egg == None
Run Code Online (Sandbox Code Playgroud)
我知道,null=True当你想让模型不指向任何其他模型时,你可以拥有ForeignKey .OneToOne只是ForeignKey的一个特例:
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
Run Code Online (Sandbox Code Playgroud)