python - Django 1.4 : Get a field in a foreign key object (null=True), 获取无或字段值

标签 python django

假设我有这些模型:

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

这个 View :

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.name 或 None if b is None,而无需在每个循环中放置 if a.b is not None: ?我的真实世界的例子要复杂得多,我正在创建一个临时对象来显示实际的数据库字段......我只想说我不想拥有所有这些 if 语句,并且不确定是否有是到达那里的另一个内置功能。我还可以创建一个类方法来获取这些外部字段(如果它们存在)或空白(如果它们不存在),但我不确定这是否是最好的方法。

最佳答案

让数据库为你做。

使用 cross-relation filter获取所有带有 bnameA,即 not null :

def DisplayIt(request):
    somestring = ""
    for a in A.objects.filter(b__name__isnull=False):
        somestring += a.b.name

要执行此操作以便在 a.b 为 None 时包含虚拟值,请使用以下内容:

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"



此外,作为旁注,不要以这种方式进行字符串连接——它是 horribly inefficient ,因为 Python 字符串是不可变的。以下要好得多:

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)



第二个旁注:上面的代码将执行查询以在 for 循环的每次迭代中获取 a.b。那可能太慢了。考虑使用 select_related一口气捕获一切。不过要小心 - 如果您的索引设置不正确,这也可能很慢。启用此功能后,我会嗅探查询和 spend some quality time with your query planner以确保您没有进行任何讨厌的非索引查找。

修改后的代码:

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)

关于python - Django 1.4 : Get a field in a foreign key object (null=True), 获取无或字段值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10097448/

相关文章:

python - 在 POST 响应中发送 OpenCV 图像

django - 从 RedirectView 重定向到包含的 URLS

Django 干草堆 : search for a term with and without accents

python - 如何使用表示 matplotlib 中的原始数据的颜色条绘制对数归一化 imshow 图

python - Odoo Studio 服务器错误计算字段,错误

python - 将元组列表中的 y 坐标与条件进行比较

python - 在python中将 float 列表打包成字节的最快方法

python - Radviz python 不显示点?

python - Django + mod_wsgi。从 Apache 的 SetEnv 设置操作系统环境变量

python - 如何在 Django forms.py 中获取远程 ip