假设我有这些模型:
class A(models.Model):
name = models.CharField(max_length=32)
b = models.ForeignKey("B", null=True)
def __unicode__(self):
return self.name
class B(models.Model):
name = models.CharField(max_length=32)
def __unicode__(self):
return self.name
这个观点:
def DisplayIt(request):
html = ""
for a in A.objects.all():
html += "<input type='text' value='" + a.b.name + "' />"
只要每个A在字段b中引用B,这都可以正常工作。但是,我在b参考字段上有null = True。当b为None时,抛出一个异常,即NoneType没有函数名,这是完全可以预期的。
显然,我可以这样做:
def DisplayIt(request):
somestring = ""
for a in A.objects.all():
if a.b is not None:
somestring += a.b.name
但是,如果我不需要,我不想这样做。那么,如果b是None,有没有办法获得b.name或None,没有在每个循环中放置if a.b is not None:
?我的真实世界的例子要复杂得多,我正在创建一个临时对象,用于显示实际数据库字段......足以说我不想拥有所有那些if语句,并且不确定是否存在到达那里是另一个内置功能。我还可以创建一个类方法来获取每个外部字段(如果它们存在)或空白(如果它们不存在),但我不确定这是最好的方法。
答案 0 :(得分:3)
让数据库为您完成。
使用cross-relation filter获取A
b
name
def DisplayIt(request):
somestring = ""
for a in A.objects.filter(b__name__isnull=False):
somestring += a.b.name
not null的所有a.b
:
def DisplayIt(request):
somestring = ""
for a in A.objects.filter(b__name__isnull=False):
somestring += a.b.name
for a in A.objects.filter(b__name__isnull=True):
somestring += "dummy value for missing b.name"
要执行此操作,以便在def DisplayIt(request):
stringparts = []
for a in A.objects.filter(b__name__isnull=False):
stringparts.append(a.b.name)
for a in A.objects.filter(b__name__isnull=True):
stringparts.append("dummy value for missing b.name")
''.join(stringparts)
为None时包含虚拟值,请使用以下命令:
def DisplayIt(request):
stringparts = []
for a in A.objects.filter(b__name__isnull=False).select_related():
stringparts.append(a.b.name)
for a in A.objects.filter(b__name__isnull=True).select_related():
stringparts.append("dummy value for missing b.name")
''.join(stringparts)
<小时/>
另外,作为旁注,不要那样做字符串连接 - 它是horribly inefficient,因为Python字符串不可变。以下是更好的:
{{1}}
<小时/>
第二方注意:上面的代码将执行查询以在for循环的每次迭代中获取a.b.这可能是缓慢的。考虑使用select_related
一次性抓取所有内容。但要小心 - 如果索引设置不正确,这也可能很慢。启用此功能后,我会嗅探查询并spend some quality time with your query planner以确保您没有进行任何令人讨厌的非索引查找。
修订代码:
{{1}}
答案 1 :(得分:3)
建立你的评论,说你想要A的实例,可能有也可能没有B.你可以破解它的工作,这通常是一个可怕的想法。使用您想要避免的冗长的pythonic方式。但这是糟糕的方式来做你想做的事情:
a.__dict__.get('b',{'name':None}).name
这使用了以下事实:所有属性都存储在对象的实际实例上的dict
对象中。您使用标准字典存取器get()
返回b
或包含您感兴趣的属性的字典。这是一个可怕的想法,但确实如此。
另外,django / python不是老派PHP。我不敢相信我在过去几周里在stackoverflow上看过多少次这样的事情,但是...... 不要强调使用HTML来生成HTML !! 这就是模板语言的用途。用它。现在就停止你正在做的事情。停止它停止它停止它。使用模板,不要尝试在视图中编写HTML。这是一个可证明错误的事情,所以停下来。停下来。