今私はDjango 1.6を使用しています
OneToOneField
に関連する2つのモデルがあります。
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つあります。 1つは属性を取得するためのtry/catchブロックを作成することであり、2つ目は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:
句は避けてください。それはいくつかを隠すことができます 問題 。
2番目の方法は次のとおりです。
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 1対1の関係 からのデフォルトの動作であるため、他の方法はありません。
そして、これは公式ドキュメントからそれを処理する例です。
>>> from Django.core.exceptions import ObjectDoesNotExist
>>> try:
>>> p2.restaurant
>>> except ObjectDoesNotExist:
>>> print("There is no restaurant here.")
There is no restaurant here.
個々のモデルクラスは、ObjectDoesNotExistを拡張するDoesNotExistと呼ばれるより具体的な例外を提供します。私の好みは次のように書くことです:
b = None
try:
b = a.ref_b
except B.DoesNotExist:
pass
hasattr
はDjango1.11で正常に動作します!短いバージョンにはgetattr
を使用できます。
getattr(self, 'field', default)
あなたの場合
b = getattr(a, 'ref_b', None)