代码和渲染字典列表 - 每个键都是一个集合的元素,值是两个集合之间的差异
Code and render dictionary list - each key is element of a set, value is difference between two sets
下面的例子完美地阐明了我的问题。
我的模特是:
人
id name
1 Alf
2 Beauty
水果
id name
1 apple
2 banana
3 cape gooseberry
4 date
5 eggplant
饮食
id person fruit
1 Alf apple
2 Beauty apple
3 Alf banana
4 Beauty cape gooseberry
5 Alf date
6 Beauty eggplant
7 Alf eggplant
8 Alf apple
9 Beauty apple
10 Alf banana
11 Beauty cape gooseberry
(当然,Diet模型中的person和fruit其实就是后台的外键)
必需
没有人没有全水果饮食吗?
如果是这样,输出=字典列表,相应的key/values对是这样的人和his/her饮食
中缺失的水果
如果不是,输出=“None”
我的想法
persons = set(Person.objects.values_list('name', flat=True).order_by('name'))
available_fruit = set(Fruit.objects.values_list('name', flat=True).order_by('name'))
fruit_in_diet = set(Diet.objects.filter(person_id=1).values_list('fruit_id', flat=True).order_by('fruit_id'))
missing_fruit = available_fruit - fruit_in_diet
完成
测试了我的想法并且它有效,分别适用于两个人 - 也就是说,单独。
它仅在我得到一组由代码中使用的每个人的正确 missing_fruits
组成的集合时才有效。
我的问题
- 如何获取字典列表作为输出?
- 我如何获得一个字典列表供两个人使用?
换句话说,我如何迭代由集合元素组成的键和由集合差异组成的值?
- 如何在 HTML 上呈现该词典列表?
我能找到的唯一相关帮助是 Finding set difference between two complex dictionaries,但我的问题从帮助结束的地方开始,如上面的完成中所示。
更新
除了最后一行,上面的代码都有效。
persons = set(Person.objects.values_list('name', flat=True).order_by('name'))
persons
{'Alf', 'Beauty'}
available_fruit = set(Fruit.objects.values_list('name', flat=True).order_by('name'))
available_fruit
{'Banana', 'Cape Gooseberry', 'Date', 'Apple', 'Eggplant'}
fruit_in_diet = set(Diet.objects.filter(person_id=1).values_list('fruit_id', flat=True).order_by('fruit_id'))
fruit_in_diet
{1, 2, 4, 5}
But, the difference between the two sets:
missing_fruit = available_fruit - fruit_in_diet
missing_fruit
{'Banana', 'Cape Gooseberry', 'Date', 'Apple', 'Eggplant'}
Same thing with the 2nd person, the difference between the two sets:
fruit_in_diet = set(Diet.objects.filter(person_id=2).values_list('fruit_id', flat=True).order_by('fruit_id'))
fruit_in_diet
{1, 3, 5}
missing_fruit = available_fruit - fruit_in_diet
missing_fruit
{'Banana', 'Cape Gooseberry', 'Date', 'Apple', 'Eggplant'}
I do not understand why this is happening.
If it could work, I would need help on how to loop over the persons rather than specify them as done in these examples.
只有 missing_fruit 行没有提供预期的答案。
我希望这是我最后一次 post 关于这个问题。 missing_fruit 行不起作用,因为它试图计算一组字符串和一个整数之间的差异。我现在已经为人员和 available_fruit 使用了 id,并且它有效。
代码如下:
persons = set(Person.objects.values_list('id', flat=True).order_by('id'))
人
{1, 2}
available_fruit = set(Fruit.objects.values_list('id', flat=True).order_by('id'))
available_fruit
{1、2、3、4、5'}
fruit_in_diet = set(Diet.objects.filter(person_id=1).values_list('fruit_id', flat=True).order_by ('fruit_id'))
fruit_in_diet
{1、2、4、5}
missing_fruit = available_fruit - fruit_in_diet
missing_fruit
{3}
fruit_in_diet = set(Diet.objects.filter(person_id=2).values_list('fruit_id', flat=True).order_by ('fruit_id'))
fruit_in_diet
{1, 3, 5}
missing_fruit = available_fruit - fruit_in_diet
missing_fruit
{2,4}
我希望能够合并显示结果如下
人不见果
阿尔夫海角鹅莓
美女香蕉,枣
有人可以帮我编写代码来进行循环,然后像上面那样显示结果。
为了得到每个人缺少的水果,我们可以使用数据库中 所有 可能的水果列表,并删除每个人存在的每个水果作为 Diet
数据库中的行。
为了能够在 HTML 模板中呈现数据,我们将在 view
中编写缺少水果的逻辑:
https://docs.djangoproject.com/en/4.0/intro/tutorial03/
# views.py
from collections import defaultdict
from django.shortcuts import render
from .models import Diet, Fruit, Person
def missing_from_diet_list(request):
# All of the Fruits in the database
available_fruit = Fruit.objects.order_by("name")
# All of the Diet objects in the database, with "Person" and "Fruit" joined in a
# single query, ordered by each Diet's person_id field.
diets = Diet.objects.select_related("person", "fruit").order_by("person__name")
# We can use a collections.defaultdict datatype that starts with the full set of
# possible fruits and removes any Fruit instances that the Person already has in
# their Diet.
missing_fruit_map = defaultdict(lambda: set(available_fruit))
for diet in diets:
person = diet.person # Used as the dictionary key
fruit = diet.fruit # Removed from the set of available_fruit for the person
missing_fruit_map[person].remove(fruit)
# To make the missing fruit data easier to work with in the template, we'll rebuild
# the missing_fruit_map object as a list of tuples so that it can be sorted by name.
for person, fruits in missing_fruit_map.items():
missing_fruit_map[person] = sorted(fruits, key=lambda fruit: fruit.name)
missing_fruit_table = sorted(missing_fruit_map.items(), key=lambda item: item[0].name)
return render(
request,
"missing_fruit.html",
{"missing_fruit_table": missing_fruit_table},
)
要了解 defaultdict
的工作原理,您可以阅读有关它的更多信息 here in the python documentation。
接下来,我们将创建 missing_fruit.html
由我们的视图呈现的文件:
<html>
<head><title>Fruits Missing from People's Diets</title></head>
<body>
<table>
<thead>
<tr>
<th>Person</th>
<th>Missing Fruits</th>
</tr>
</thead>
<tbody>
{% for person, missing_fruits in people_with_missing_fruit.items %}
<tr>
<td>{{ person.name }}</td>
<td>
<ol>
{% for fruit in missing_fruits %}
<li>{{ fruit.name }}</li>
{% endfor %}
</ol>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
正确答案其实连代码都不需要解释。首要任务是找出每个人是否有任何水果没有拿走。
使用 distinct() 并指定 fruit 和 person 字段会产生不同的 person 和 fruit 组合,如果这些组合少于预期,(水果类型 * 人数)则一些水果没有被采摘由某人
https://docs.djangoproject.com/en/4.0/ref/models/querysets/#distinct
幸好我在 PostgreSQL 上!
下面的例子完美地阐明了我的问题。
我的模特是:
人
id name
1 Alf
2 Beauty
水果
id name
1 apple
2 banana
3 cape gooseberry
4 date
5 eggplant
饮食
id person fruit
1 Alf apple
2 Beauty apple
3 Alf banana
4 Beauty cape gooseberry
5 Alf date
6 Beauty eggplant
7 Alf eggplant
8 Alf apple
9 Beauty apple
10 Alf banana
11 Beauty cape gooseberry
(当然,Diet模型中的person和fruit其实就是后台的外键)
必需
没有人没有全水果饮食吗?
如果是这样,输出=字典列表,相应的key/values对是这样的人和his/her饮食
中缺失的水果如果不是,输出=“None”
我的想法
persons = set(Person.objects.values_list('name', flat=True).order_by('name'))
available_fruit = set(Fruit.objects.values_list('name', flat=True).order_by('name'))
fruit_in_diet = set(Diet.objects.filter(person_id=1).values_list('fruit_id', flat=True).order_by('fruit_id'))
missing_fruit = available_fruit - fruit_in_diet
完成
测试了我的想法并且它有效,分别适用于两个人 - 也就是说,单独。
它仅在我得到一组由代码中使用的每个人的正确 missing_fruits
组成的集合时才有效。
我的问题
- 如何获取字典列表作为输出?
- 我如何获得一个字典列表供两个人使用? 换句话说,我如何迭代由集合元素组成的键和由集合差异组成的值?
- 如何在 HTML 上呈现该词典列表?
我能找到的唯一相关帮助是 Finding set difference between two complex dictionaries,但我的问题从帮助结束的地方开始,如上面的完成中所示。
更新 除了最后一行,上面的代码都有效。
persons = set(Person.objects.values_list('name', flat=True).order_by('name'))
persons
{'Alf', 'Beauty'}
available_fruit = set(Fruit.objects.values_list('name', flat=True).order_by('name'))
available_fruit
{'Banana', 'Cape Gooseberry', 'Date', 'Apple', 'Eggplant'}
fruit_in_diet = set(Diet.objects.filter(person_id=1).values_list('fruit_id', flat=True).order_by('fruit_id'))
fruit_in_diet
{1, 2, 4, 5}
But, the difference between the two sets:
missing_fruit = available_fruit - fruit_in_diet
missing_fruit
{'Banana', 'Cape Gooseberry', 'Date', 'Apple', 'Eggplant'}
Same thing with the 2nd person, the difference between the two sets:
fruit_in_diet = set(Diet.objects.filter(person_id=2).values_list('fruit_id', flat=True).order_by('fruit_id'))
fruit_in_diet
{1, 3, 5}
missing_fruit = available_fruit - fruit_in_diet
missing_fruit
{'Banana', 'Cape Gooseberry', 'Date', 'Apple', 'Eggplant'}
I do not understand why this is happening.
If it could work, I would need help on how to loop over the persons rather than specify them as done in these examples.
只有 missing_fruit 行没有提供预期的答案。
我希望这是我最后一次 post 关于这个问题。 missing_fruit 行不起作用,因为它试图计算一组字符串和一个整数之间的差异。我现在已经为人员和 available_fruit 使用了 id,并且它有效。
代码如下:
persons = set(Person.objects.values_list('id', flat=True).order_by('id'))
人 {1, 2}
available_fruit = set(Fruit.objects.values_list('id', flat=True).order_by('id')) available_fruit {1、2、3、4、5'}
fruit_in_diet = set(Diet.objects.filter(person_id=1).values_list('fruit_id', flat=True).order_by ('fruit_id')) fruit_in_diet {1、2、4、5}
missing_fruit = available_fruit - fruit_in_diet missing_fruit {3}
fruit_in_diet = set(Diet.objects.filter(person_id=2).values_list('fruit_id', flat=True).order_by ('fruit_id')) fruit_in_diet {1, 3, 5}
missing_fruit = available_fruit - fruit_in_diet missing_fruit {2,4}
我希望能够合并显示结果如下
人不见果 阿尔夫海角鹅莓 美女香蕉,枣
有人可以帮我编写代码来进行循环,然后像上面那样显示结果。
为了得到每个人缺少的水果,我们可以使用数据库中 所有 可能的水果列表,并删除每个人存在的每个水果作为 Diet
数据库中的行。
为了能够在 HTML 模板中呈现数据,我们将在 view
中编写缺少水果的逻辑:
https://docs.djangoproject.com/en/4.0/intro/tutorial03/
# views.py
from collections import defaultdict
from django.shortcuts import render
from .models import Diet, Fruit, Person
def missing_from_diet_list(request):
# All of the Fruits in the database
available_fruit = Fruit.objects.order_by("name")
# All of the Diet objects in the database, with "Person" and "Fruit" joined in a
# single query, ordered by each Diet's person_id field.
diets = Diet.objects.select_related("person", "fruit").order_by("person__name")
# We can use a collections.defaultdict datatype that starts with the full set of
# possible fruits and removes any Fruit instances that the Person already has in
# their Diet.
missing_fruit_map = defaultdict(lambda: set(available_fruit))
for diet in diets:
person = diet.person # Used as the dictionary key
fruit = diet.fruit # Removed from the set of available_fruit for the person
missing_fruit_map[person].remove(fruit)
# To make the missing fruit data easier to work with in the template, we'll rebuild
# the missing_fruit_map object as a list of tuples so that it can be sorted by name.
for person, fruits in missing_fruit_map.items():
missing_fruit_map[person] = sorted(fruits, key=lambda fruit: fruit.name)
missing_fruit_table = sorted(missing_fruit_map.items(), key=lambda item: item[0].name)
return render(
request,
"missing_fruit.html",
{"missing_fruit_table": missing_fruit_table},
)
要了解 defaultdict
的工作原理,您可以阅读有关它的更多信息 here in the python documentation。
接下来,我们将创建 missing_fruit.html
由我们的视图呈现的文件:
<html>
<head><title>Fruits Missing from People's Diets</title></head>
<body>
<table>
<thead>
<tr>
<th>Person</th>
<th>Missing Fruits</th>
</tr>
</thead>
<tbody>
{% for person, missing_fruits in people_with_missing_fruit.items %}
<tr>
<td>{{ person.name }}</td>
<td>
<ol>
{% for fruit in missing_fruits %}
<li>{{ fruit.name }}</li>
{% endfor %}
</ol>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
正确答案其实连代码都不需要解释。首要任务是找出每个人是否有任何水果没有拿走。
使用 distinct() 并指定 fruit 和 person 字段会产生不同的 person 和 fruit 组合,如果这些组合少于预期,(水果类型 * 人数)则一些水果没有被采摘由某人
https://docs.djangoproject.com/en/4.0/ref/models/querysets/#distinct
幸好我在 PostgreSQL 上!