Django - 计算模板中每行过滤后的模型实例 table
Django - Counting filtered model instances per row in a template table
假设我有以下 Django 模型:
class House(Model):
author = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
title = CharField(max_length=200, default='')
text = TextField(default='')
rooms = IntegerField(null=True)
class Room(Model):
author = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
title = CharField(max_length=200, default='')
text = TextField(default='')
house = CharField(max_length=200, default='')
furniture = IntegerField(null=True)
class Furniture(model):
author = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
title = CharField(max_length=200, default='')
text = TextField(default='')
room = CharField(max_length=200, default='')
我想在模板中生成以下 table:
Room
In house
Amount of furniture
Living Room
Summer house
5
Kitchen
Summer house
8
Bedroom
Summer house
2
Bathroom
Main house
3
其中“家具数量”列计算“家具”模型的实例,其中字段“房间”等于该行“房间”列中的条目。
我正在尝试弄清楚如何做到这一点,我找到了几种不同的方法 - 从最多 ideal/pythonic 到最少 ideal/pythonic。
- 在模型中构建某种机制。这将是完美的,但我似乎找不到任何明显的方法来做到这一点。
- 在 views.py 的视图中添加一个生成字典的函数。很容易构建(收集“房间”的名称,制作一个 for 循环,对模型“家具”上的每个房间进行过滤查询,添加一个计数器变量,并构建一个字典)但不是很灵活或 pythonic。
- 使用数据tables 等第三方模块。感觉有点矫枉过正 - 但可能是更好的长期解决方案?
- 在模板语言中设置一些真正的恶作剧。由于您不能在模板中声明变量,我想这将是一个由嵌套循环、条件和自定义模板标签组成的蜘蛛网。
我应该选择哪种方法?
您应该 ForeignKey
[Django-doc] to link models. This is part of database normalization [wiki] 来防止 数据重复 并使数据库更易于管理:
class House(Model):
author = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
title = CharField(max_length=200, default='')
text = TextField(default='')
class Room(Model):
author = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
title = CharField(max_length=200, default='')
text = TextField(default='')
house = <strong>ForeignKey(</strong>House, on_delete=CASCADE<strong>)</strong>
class Furniture(model):
author = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
title = CharField(max_length=200, default='')
text = TextField(default='')
room = <strong>ForeignKey(Room</strong>, on_delete=CASCADE<strong>)</strong>
也不需要存储Room
或Furniture
的数量:您可以在需要时确定。在您看来,您可以使用以下方式查询 Room
模型:
from <em>app_name</em>.models import Room
from django.db.models import Count
def some_view(request):
rooms = Room.objects.select_related('house').annotate(
<strong>num_furniture=Count('furniture')</strong>
)
return render(request, '<em>app_name</em>/some_template.html', {'rooms': rooms})
因此我们在这里用 Funiture
和 Count('furniture')
的相关数量注释 Room
s。数据库将简单地计算每个 Room
的 Furniture
的数量:这更健壮,因为它在创建、更新、删除 Furniture
、Room
时不需要逻辑,等等
然后在模板中,您可以使用以下方式呈现 table:
<table>
<thead>
<tr><th>Room</th><th>In house</th><th>Amount of furniture</th></tr>
</thead>
<tbody>
{% for <strong>room in rooms</strong> %}
<tr><td>{{ room.title }}</td><td>{{ room<strong>.house.title</strong> }}</td><td>{{ room<strong>.num_furniture</strong> }}</td></tr>
{% endfor %}
</tbody>
</table>
假设我有以下 Django 模型:
class House(Model):
author = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
title = CharField(max_length=200, default='')
text = TextField(default='')
rooms = IntegerField(null=True)
class Room(Model):
author = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
title = CharField(max_length=200, default='')
text = TextField(default='')
house = CharField(max_length=200, default='')
furniture = IntegerField(null=True)
class Furniture(model):
author = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
title = CharField(max_length=200, default='')
text = TextField(default='')
room = CharField(max_length=200, default='')
我想在模板中生成以下 table:
Room | In house | Amount of furniture |
---|---|---|
Living Room | Summer house | 5 |
Kitchen | Summer house | 8 |
Bedroom | Summer house | 2 |
Bathroom | Main house | 3 |
其中“家具数量”列计算“家具”模型的实例,其中字段“房间”等于该行“房间”列中的条目。
我正在尝试弄清楚如何做到这一点,我找到了几种不同的方法 - 从最多 ideal/pythonic 到最少 ideal/pythonic。
- 在模型中构建某种机制。这将是完美的,但我似乎找不到任何明显的方法来做到这一点。
- 在 views.py 的视图中添加一个生成字典的函数。很容易构建(收集“房间”的名称,制作一个 for 循环,对模型“家具”上的每个房间进行过滤查询,添加一个计数器变量,并构建一个字典)但不是很灵活或 pythonic。
- 使用数据tables 等第三方模块。感觉有点矫枉过正 - 但可能是更好的长期解决方案?
- 在模板语言中设置一些真正的恶作剧。由于您不能在模板中声明变量,我想这将是一个由嵌套循环、条件和自定义模板标签组成的蜘蛛网。
我应该选择哪种方法?
您应该 ForeignKey
[Django-doc] to link models. This is part of database normalization [wiki] 来防止 数据重复 并使数据库更易于管理:
class House(Model):
author = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
title = CharField(max_length=200, default='')
text = TextField(default='')
class Room(Model):
author = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
title = CharField(max_length=200, default='')
text = TextField(default='')
house = <strong>ForeignKey(</strong>House, on_delete=CASCADE<strong>)</strong>
class Furniture(model):
author = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
title = CharField(max_length=200, default='')
text = TextField(default='')
room = <strong>ForeignKey(Room</strong>, on_delete=CASCADE<strong>)</strong>
也不需要存储Room
或Furniture
的数量:您可以在需要时确定。在您看来,您可以使用以下方式查询 Room
模型:
from <em>app_name</em>.models import Room
from django.db.models import Count
def some_view(request):
rooms = Room.objects.select_related('house').annotate(
<strong>num_furniture=Count('furniture')</strong>
)
return render(request, '<em>app_name</em>/some_template.html', {'rooms': rooms})
因此我们在这里用 Funiture
和 Count('furniture')
的相关数量注释 Room
s。数据库将简单地计算每个 Room
的 Furniture
的数量:这更健壮,因为它在创建、更新、删除 Furniture
、Room
时不需要逻辑,等等
然后在模板中,您可以使用以下方式呈现 table:
<table>
<thead>
<tr><th>Room</th><th>In house</th><th>Amount of furniture</th></tr>
</thead>
<tbody>
{% for <strong>room in rooms</strong> %}
<tr><td>{{ room.title }}</td><td>{{ room<strong>.house.title</strong> }}</td><td>{{ room<strong>.num_furniture</strong> }}</td></tr>
{% endfor %}
</tbody>
</table>