2014-10-03 182 views
0

我在模型上定義了一對一關係。我們稱之爲父模型A和相關模型B. B並不總是存在。當我與A的實例交互時,如何確定B是否存在而不必捕獲DoesNotExist?當我嘗試訪問B的一個實例時(例如print a.b),我收到一個DoesNotExist異常。當存在與其工作關係相對應的DB行時。這是在Django 1.5。如何檢查對象關係是否已填充DoesNotExist

簡化模型定義了我的頭頂部(以這種形式未測試):

class A: 
    ... 

class B: 
    a = models.OneToOneField(A, related_name='a') 
    name = models.TextField(...) 

fields = ['b__name'] 
a = A.object.filter(pk=id).selected_related(*fields) 
print(a.b) 

表B有A_ID的外鍵。

我的問題的原因是確定是否有更簡潔的方式通過API執行此操作,而不是捕獲異常。

+0

你能展示你的模型定義嗎? – falsetru 2014-10-03 14:26:01

+0

爲什麼你不想捕捉B.DoesNotExist?這是非常標準的異常處理。 – scoopseven 2014-10-03 14:46:12

+0

你的ForeignKey字段是否允許空值? – Brandon 2014-10-03 14:55:00

回答

1

如果我理解這個正確,首先屬性「related_name」用於從反向外鍵對象是指當前對象,因此模型的定義應該是這樣的:

class A: 
    ... 

class B: 
    a = models.OneToOneField(A, related_name='alias_for_b') 
    name = models.TextField(...) 

和驗證碼可能很簡單:

if hasattr(a, 'alias_for_b'): 
    print(a.b) or print(a.alias_for_b) 

希望這有助於!

+0

'hasattr'似乎工作。謝謝您的幫助。 – Brad 2014-10-06 13:13:55

0

假設你有你的實例Aa。正如您正確地說,您可以使用類似print(a.b)(Python 3語法)的方式訪問Bb的相關實例。如果可能沒有相關項目,並且您不希望用戶出現錯誤,那麼您需要將該呼叫打包到b以上。喜歡的東西:

try: 
    print(a.b) 
except: 
    print('Nothing to see here') 

來檢查b的存在設法提出之前,不會做,如果它不存在。

另外,你可以從另一個方向來解決這個問題。給定一個實例a,你可以查找B.objects.filter(your_relation_name=a)。這種方式不會涉及任何錯誤捕獲,只是一個空白的查詢集,如果沒有這樣的b存在。

+0

爲什麼捕捉異常會比捕捉DoesNotExist更好? – 2014-10-03 16:06:27

+0

我相信這是[更高效](http://stackoverflow.com/a/6383390/1280784)。 – 2014-10-03 16:08:00

+0

我不會關心效率,它更容易出錯,因爲它可以捕捉所有的異常,甚至意外的異常。 – Brad 2014-10-03 17:49:20