所以我试图获取所有能够在我的模板中显示的值。但是我自己也遇到过这个问题:
我有这些模型:
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'}]
有办法做到这一点吗?或者还有其他方法可以在 View 中执行此操作吗?
注意:我知道为 Django 中的每个类设置一个 ID 是不对的,但在我工作的地方这是一种标准。所以我无法改变它。
最佳答案
然后您应该以相反的方式执行此操作:
result = list(Project.objects.values(
'description',
<b>ProjectName=F('pm__PMNumber')</b>
))
对于不存在 PM
的 Project
,None
将用于 ProjectName
。如果同一个Project
有多个PM
,则将添加所有这些PM
。
话虽如此,我不明白为什么您将 lated_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",
<b>related_name='pm_set'</b>
)
然后你查询:
result = list(Project.objects.values(
'description',
<b>ProjectName=F('pm_set__PMNumber')</b>
))
您可以将缺少的 ProjectName
替换为项目的 description
:
from django.db.models.functions import Coalesce
result = list(Project.objects.values(
'description',
<b>ProjectName=Coalesce('pm_set__PMNumber', 'description')</b>
))
您还可以将列表后处理到包含字典的字典,其中 projectName
(或者更好的 projectNames
是一个列表,与:
from itertools import groupby
from operator import itemgetter
from django.db.models.functions import Coalesce
result = list(Project.objects.values(
'description',
<b>ProjectName=Coalesce('pm_set__PMNumber', 'description')</b>
)<b>.order_by('description')</b>)
result = [
{ 'description': k, 'projectNames': list(map(itemgetter('projectName'), vs)) }
for k, vs in groupby(itemgetter('description'), result)
]
或者我们可以为没有 PM
的 Projects
创建一个空列表:
from itertools import groupby
from operator import itemgetter
result = list(Project.objects.values(
'description',
<b>ProjectName=F('pm_set__PMNumber')</b>
)<b>.order_by('description')</b>)
result = [
{ 'description': k, 'projectNames': list(filter(None, map(itemgetter('projectName'), vs))) }
for k, vs in groupby(itemgetter('description'), result)
]
关于python - Django查询集在查询中获取空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61375370/