2014-09-20 124 views
9

存在现在我使用Django 1.6检查一个OneToOne关系在Django

我有两个模型涉及用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 - 我也试图检查属性中,但不工作:

b = a.ref_b if hasattr(a, 'ref_b') else None 

你达到了同样的问题,朋友们?请指点一下,谢谢!

+0

我认为这会对你有效,请记住在2次以后改变你的班级名称。 b = hasattr(a_class_object,'b class')和a.ref_b或None。我正在使用它并为我工作。 – 2014-09-20 05:09:18

+0

@Yogesh我不太清楚,请您提供更详细的解决方案? – 2014-09-20 06:40:23

+0

'hasattr'似乎对Django 1.8.17和Python 2来说工作得很好。 – beruic 2017-06-22 08:53:10

回答

17

所以你至少有两种方法来检查。 首先是创建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. 
+0

很好的答案!谢谢! – 2016-02-08 21:22:43

7

单个模型类提供了一个更具体的异常,称为DoesNotExist,它扩展了ObjectDoesNotExist。我的首选是这样写的:

b = None 
try: 
    b = a.ref_b 
except B.DoesNotExist: 
    pass 
+0

为什么不把'b = None'放在'except'子句中? (保存一行) – nivcaner 2017-10-10 07:47:21