2014-10-03 39 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