【问题标题】:Django queryset get empty values in queryDjango queryset 在查询中获取空值
【发布时间】:2020-08-06 01:53:15
【问题描述】:

所以我试图让所有值能够显示在我的模板中。但是我自己也遇到过这个问题:

我有这些模型:

class Project(models.Model):
    projectId = models.AutoField(primary_key=True, db_column="Id", db_index=True, verbose_name='Project ID')
    description = models.CharField(max_length=900)

class PM(models.Model):
    PMid = models.AutoField(primary_key=True, db_column="Id", db_index=True)
    PMNumber = models.CharField(max_length=50, unique=True, db_column="PMNumber")
    description = models.CharField(max_length=600)
    projectId = models.ForeignKey(Project, on_delete=models.CASCADE,
                                  db_column="ProjectID", related_name='+')

我正在尝试使用它们各自的 PMNumber 获取所有项目。为此我正在尝试这样的事情:

fpm = PM.objects.all()
projects = []
for i in fpm:
   projects.append({'ProjectName': i.projectId.description, 'PMNumber': i.PMNumber})

之后的结果是这样的

[{'ProjectName': 'pr1', 'PMNumber': '119508-01'}, {'ProjectName': 'pr1', 'PMNumber': '119490-01'}]

但是,我仍然缺少一些没有相关 PM 的项目,我希望查询集中的所有项目都能够在模板中显示它们,而不仅仅是具有 PM 的项目。它应该看起来像这样:

[{'ProjectName': 'pr2', 'PMNumber':'None'}, {'ProjectName':'pr3' , 'PMNumber':'None'}, {'ProjectName': 'pr1', 'PMNumber': '119508-01'}, {'ProjectName': 'pr1', 'PMNumber': '119490-01'}]

有没有办法做到这一点?还是在视图中有其他方法可以做到这一点?

注意:我知道在 Django 中为每个类设置一个 ID 是不对的,但在我工作的地方这是一种标准。所以我不能改变它。

【问题讨论】:

  • 我在projects.append 中看到语法错误。字典从未打开?
  • 是的,你是对的,这只是我写问题时的语法错误。它在代码中写得很好。我已经编辑了这个问题。感谢您的关注:D

标签: python django django-views django-templates


【解决方案1】:

然后你应该以相反的方式执行此操作:

result = list(Project.objects.values(
    'description',
    ProjectName=F('pm__PMNumber')
))

对于不存在PMProjects,None 将用于ProjectName。如果同一个Project有多个PMs,则将所有这些PMs添加。

话虽如此,我不明白您为什么将related_name 设置为realted_name='+'。这是反向关系的名称,因此最好将其设置为:

class PM(models.Model):
    PMid = models.AutoField(primary_key=True, db_column="Id", db_index=True)
    PMNumber = models.CharField(max_length=50, unique=True, db_column="PMNumber")
    description = models.CharField(max_length=600)
    projectId = models.ForeignKey(
        Project, on_delete=models.CASCADE,
        db_column="ProjectID",
        related_name='pm_set'
)

然后你查询:

result = list(Project.objects.values(
    'description',
    ProjectName=F('pm_set__PMNumber')
))

您可以将缺少的ProjectName 替换为项目的description

from django.db.models.functions import Coalesce

result = list(Project.objects.values(
    'description',
    ProjectName=Coalesce('pm_set__PMNumber', 'description')
))

您还可以将列表后处理为包含projectName(或者更好的projectNames列表的字典,其中:

from itertools import groupby
from operator import itemgetter
from django.db.models.functions import Coalesce

result = list(Project.objects.values(
    'description',
    ProjectName=Coalesce('pm_set__PMNumber', 'description')
).order_by('description'))

result = [ 
    { 'description': k, 'projectNames': list(map(itemgetter('projectName'), vs)) }
    for k, vs in groupby(itemgetter('description'), result)
]

或者我们可以为 Projects 创建一个没有 PM 的空列表:

from itertools import groupby
from operator import itemgetter

result = list(Project.objects.values(
    'description',
    ProjectName=F('pm_set__PMNumber')
).order_by('description'))

result = [ 
    { 'description': k, 'projectNames': list(filter(None, map(itemgetter('projectName'), vs))) }
    for k, vs in groupby(itemgetter('description'), result)
]

【讨论】:

  • 哦,我是这样使用它的,所以我可以在 Django Admin 中看到它作为另一个模型的一部分,我无法以正确的方式添加它。无论如何我应该改变它吗?我理解你写的内容,但我需要 ProjectName 不为空,如果 PM 没有任何内容,我需要它为空。我可以这样做吗?
  • @DiegoDuarte:鉴于PM 不存在,究竟应该把what 放在ProjectName 中吗?
  • 让我得到一个更好的上下文:我正在尝试在 HTML 模板的列表中显示所有可用的项目,但我还需要来自项目的 PMs 让它们能够显示哪些有PM,哪些没有。因此,鉴于PM 不存在,ProjectName 应该与项目中的description 相同。我希望这是有道理的
  • 它应该看起来像这样:Project1: PMS: 10292, 10282, Project2:, Project3: PMS: xxxx, xxxx
  • @DiegoDuarte:也许您可以看看可能的答案生成的输出,并评论需要更改的内容。
猜你喜欢
  • 2020-11-29
  • 1970-01-01
  • 2018-10-28
  • 1970-01-01
  • 2021-10-09
  • 2013-04-26
  • 2013-01-07
  • 2012-04-07
  • 1970-01-01
相关资源
最近更新 更多