Alf*_*ang 14 python django model one-to-one
现在我正在使用django 1.6
我有两个模型涉及一个OneToOneField.
class A(models.Model):
pass
class B(models.Model):
ref_a = models.OneToOneField(related_name='ref_b', null=True)
Run Code Online (Sandbox Code Playgroud)
首先看我指出问题的代码:
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
Run Code Online (Sandbox Code Playgroud)
现在的问题是,如果我想检查一个A对象,判断它是否存在B引用它的对象.我能怎么做?
我尝试的有效方法只是尝试捕获异常,但还有其他更漂亮的方法吗?
我的努力:
1 - 以下代码有效,但太难看了!
b = None
try:
b = a.ref_b
except:
pass
Run Code Online (Sandbox Code Playgroud)
2 - 我也尝试检查a中的属性,但不工作:
b = a.ref_b if hasattr(a, 'ref_b') else None
Run Code Online (Sandbox Code Playgroud)
朋友们,你遇到同样的问题吗?请指点我,谢谢!
Mr.*_*fee 21
所以你至少有两种检查方法.首先是创建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)
Run Code Online (Sandbox Code Playgroud)
请尽量避免裸except:条款.它可以隐藏一些问题.
第二种方式是:
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)
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,您可以使用它,没有任何例外:
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
Run Code Online (Sandbox Code Playgroud)
没有其他办法,因为抛出异常是Django One to One关系的默认行为.
这是从官方文档处理它的例子.
>>> from django.core.exceptions import ObjectDoesNotExist
>>> try:
>>> p2.restaurant
>>> except ObjectDoesNotExist:
>>> print("There is no restaurant here.")
There is no restaurant here.
Run Code Online (Sandbox Code Playgroud)
单个模型类提供了一个名为DoesNotExist的更具体的异常,它扩展了ObjectDoesNotExist.我的偏好是这样写:
b = None
try:
b = a.ref_b
except B.DoesNotExist:
pass
Run Code Online (Sandbox Code Playgroud)
hasattr与 Django1.11 一起工作正常!您可以使用getattr较短的版本:
getattr(self, 'field', default)
Run Code Online (Sandbox Code Playgroud)
在你的情况下
b = getattr(a, 'ref_b', None)
Run Code Online (Sandbox Code Playgroud)
https://docs.python.org/3.6/library/functions.html#getattr