[英]Django queryset get empty values in query
So I'm trying to get all the values to be able to display in my templates.所以我试图让所有的值能够显示在我的模板中。 However I have encountered myself with this problem:但是我遇到了这个问题:
I have these models:我有这些模型:
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='+')
And I'm trying to get all the projects with their respective PMNumber.我正在尝试使用它们各自的 PMNumber 获取所有项目。 For which I'm trying something like this:我正在尝试这样的事情:
fpm = PM.objects.all()
projects = []
for i in fpm:
projects.append({'ProjectName': i.projectId.description, 'PMNumber': i.PMNumber})
After that the result is like this之后结果是这样的
[{'ProjectName': 'pr1', 'PMNumber': '119508-01'}, {'ProjectName': 'pr1', 'PMNumber': '119490-01'}]
However, I'm still missing some projects that don't have a PM related to them, I want all the projects in the queryset to be able to show them in a template, not just the ones that have a PM.但是,我仍然缺少一些没有与之相关的 PM 的项目,我希望查询集中的所有项目都能够在模板中显示它们,而不仅仅是具有 PM 的项目。 It should look something like this:它应该看起来像这样:
[{'ProjectName': 'pr2', 'PMNumber':'None'}, {'ProjectName':'pr3' , 'PMNumber':'None'}, {'ProjectName': 'pr1', 'PMNumber': '119508-01'}, {'ProjectName': 'pr1', 'PMNumber': '119490-01'}]
Is there a way to do this?有没有办法做到这一点? or is there another way to do this in the views?还是在视图中有另一种方法可以做到这一点?
Note: I know that setting an ID for each class in Django is not right, but it's kind of a standard in the place where I work at.注意:我知道在 Django 中为每个 class 设置一个 ID 是不对的,但这在我工作的地方是一种标准。 So I can't change it.所以我无法改变它。
You should then do this the opposite way:然后,您应该以相反的方式执行此操作:
result = list(Project.objects.values(
'description',
ProjectName=F('pm__PMNumber')
))
For the Project
s for which no PM
exists, None
will be used for ProjectName
.对于不存在PM
的Project
, ProjectName
将使用None
。 If there are multiple PM
s for the same Project
, all these PM
s will be added.如果同一个Project
有多个PM
,则将添加所有这些PM
。
That being said, I do not see why you set related_name
to realted_name='+'
.话虽如此,我不明白您为什么将 related_name 设置为related_name
realted_name='+'
。 This is the name of the relation in reverse, so likely it is better to set it to something like:这是反向关系的名称,因此最好将其设置为:
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'
)
Then you query with:然后你查询:
result = list(Project.objects.values(
'description',
ProjectName=F('pm_set__PMNumber')
))
You can replace a missing ProjectName
with the description
of the project with:您可以将缺少的ProjectName
替换为项目的description
:
from django.db.models.functions import Coalesce
result = list(Project.objects.values(
'description',
ProjectName=Coalesce('pm_set__PMNumber', 'description')
))
You can also post-process the list to a dictionary that contains dictionaries where the projectName
(or perhaps better projectNames
is a list , with:您还可以将列表后处理到包含字典的字典,其中projectName
(或者更好的projectNames
是list ,具有:
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)
]
or we can make an empty list for Projects
with no PM
with:或者我们可以为没有PM
的Projects
创建一个空列表:
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)
]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.