检查 Django 中是不是存在 OneToOne 关系
Posted
技术标签:
【中文标题】检查 Django 中是不是存在 OneToOne 关系【英文标题】:Check if a OneToOne relation exists in Django检查 Django 中是否存在 OneToOne 关系 【发布时间】:2014-11-14 16:49:05 【问题描述】:现在我使用的是 django 1.6
我有两个模型与OneToOneField
相关。
class A(models.Model):
pass
class B(models.Model):
ref_a = models.OneToOneField(related_name='ref_b', null=True)
首先看我指出问题的代码:
a1 = A.objects.create()
a2 = A.objects.create()
b1 = B.objects.create()
b2 = B.objects.create(ref_a=a2)
# then I call:
print(a1.ref_b) # DoesNotExist Exception raised
print(a2.ref_b) # returns b2
print(b1.ref_a) # returns None
print(b2.ref_a) # returns a2
现在的问题是,如果我要检查一个A
对象,判断它是否存在引用它的B
对象。我该怎么办?
我尝试的有效方法只是尝试捕获异常,但是还有其他更漂亮的方法吗?
我的努力:
1 - 下面的代码有效,但是太丑了!
b = None
try:
b = a.ref_b
except:
pass
2 - 我也尝试检查 a 中的属性,但不起作用:
b = a.ref_b if hasattr(a, 'ref_b') else None
朋友们,你们也遇到同样的问题吗?请指点一下,谢谢!
【问题讨论】:
我认为这对你有用,请记住至少在 2 后更改你的班级名称。 b = hasattr(a_class_object, 'b class') 和 a.ref_b 或无。我正在使用相同的产品并为我工作。 @Yogesh 我不太明白,能否请您发布更详细的解决方案?hasattr
在 Django 1.8.17 和 Python 2 上似乎可以正常工作。
【参考方案1】:
因此,您至少有两种检查方法。
首先是创建try/catch块来获取属性,其次是使用hasattr
。
class A(models.Model):
def get_B(self):
try:
return self.b
except:
return None
class B(models.Model):
ref_a = models.OneToOneField(related_name='ref_b', null=True)
请尽量避免裸露的except:
子句。它可以隐藏一些problems。
第二种方式是:
class A(models.Model):
def get_B(self):
if(hasattr(self, 'b')):
return self.b
return None
class B(models.Model):
ref_a = models.OneToOneField(related_name='ref_b', null=True)
在这两种情况下,您都可以毫无例外地使用它:
a1 = A.objects.create()
a2 = A.objects.create()
b1 = B.objects.create()
b2 = B.objects.create(ref_a=a2)
# then I call:
print(a1.get_b) # No exception raised
print(a2.get_b) # returns b2
print(b1.a) # returns None
print(b2.a) # returns a2
没有其他办法,因为抛出异常是 Django One to One relationships 的默认行为。
这是从官方文档中处理它的示例。
>>> from django.core.exceptions import ObjectDoesNotExist
>>> try:
>>> p2.restaurant
>>> except ObjectDoesNotExist:
>>> print("There is no restaurant here.")
There is no restaurant here.
【讨论】:
很好的答案!谢谢!【参考方案2】:各个模型类提供了一个更具体的例外,称为 DoesNotExist,它扩展了 ObjectDoesNotExist。我的偏好是这样写:
b = None
try:
b = a.ref_b
except B.DoesNotExist:
pass
【讨论】:
为什么不把b = None
放在except
子句中? (保存一行)【参考方案3】:
hasattr
与 Django1.11 配合得很好!
您可以使用getattr
来获得更短的版本:
getattr(self, 'field', default)
你的情况
b = getattr(a, 'ref_b', None)
https://docs.python.org/3.6/library/functions.html#getattr
【讨论】:
以上是关于检查 Django 中是不是存在 OneToOne 关系的主要内容,如果未能解决你的问题,请参考以下文章
Django:为啥要为 UserProfile 创建 OneToOne 而不是子类化 auth.User?