2014-09-20 69 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