为相关对象编写按请求过滤
Writing on-request filtering for related objects
假设我们有以下模型
class Category(models.Model):
name = models.CharField(max_length=254)
class Item(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="items")
name = models.CharField(max_length=254)
state = models.ForeignKey(State, on_delete=models.CASCADE)
类别及其项目如下所示
def view(request):
categories = Category.objects.all()
pass
{% for category in categories %}
{{ category.name }}
{% for item in category.items.all %}
{{ item.name }}
{% endfor %}
{% endfor %}
在这个结构中,我想为列出的'items'编写按需过滤。
def view(request):
...
queryset = ???
state = request.GET.get('state')
if state:
queryset = queryset.filter(state__name=state)
问题是定义 'queryset'。因为,项目被列为类别的相关对象。
能不能做好?或者我需要更改设计吗?
你可以看看我的设计更清楚。
Low fidelity design
您在“类别的项目对象”字段中的 related_name
应命名为“项目”。然后 category.items.all 将为您提供该类别中的项目列表。查看 documentation.
中的示例
class Tag(models.Model):
article = models.ForeignKey(
Article,
on_delete=models.CASCADE,
related_name="tags",
)
name = models.CharField(max_length=255)
要根据类别过滤项目,您可以在请求中传递类别的 PK,并根据这些特定类别进行过滤。
views.py
def your_view(request):
...
list_of_your_category_ids = [1,4] #get them as a list from frontend
list_of_your_state_names = [1,2]
queryset = Item.objects.filter(
category__in=list_of_your_category_ids,
state__code__in=list_of_your_category_names
)
这将为您提供所需的查询集。现在你需要做的就是用它们的类别重新组合这个查询集。
Django 提供了一个 regroup 模板标签来做这件事。
{% regroup queryset by category as categories_list %}
<ul>
{% for category in categories_list %}
<li>
{{category.grouper}}
<ul>
{% for item in category.list %}
<li>
{{item}}: state - {{item.state.code}}
</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
https://i.stack.imgur.com/TbTpz.png
假设我们有以下模型
class Category(models.Model):
name = models.CharField(max_length=254)
class Item(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="items")
name = models.CharField(max_length=254)
state = models.ForeignKey(State, on_delete=models.CASCADE)
类别及其项目如下所示
def view(request):
categories = Category.objects.all()
pass
{% for category in categories %}
{{ category.name }}
{% for item in category.items.all %}
{{ item.name }}
{% endfor %}
{% endfor %}
在这个结构中,我想为列出的'items'编写按需过滤。
def view(request):
...
queryset = ???
state = request.GET.get('state')
if state:
queryset = queryset.filter(state__name=state)
问题是定义 'queryset'。因为,项目被列为类别的相关对象。
能不能做好?或者我需要更改设计吗?
你可以看看我的设计更清楚。
Low fidelity design
您在“类别的项目对象”字段中的 related_name
应命名为“项目”。然后 category.items.all 将为您提供该类别中的项目列表。查看 documentation.
class Tag(models.Model):
article = models.ForeignKey(
Article,
on_delete=models.CASCADE,
related_name="tags",
)
name = models.CharField(max_length=255)
要根据类别过滤项目,您可以在请求中传递类别的 PK,并根据这些特定类别进行过滤。
views.py
def your_view(request):
...
list_of_your_category_ids = [1,4] #get them as a list from frontend
list_of_your_state_names = [1,2]
queryset = Item.objects.filter(
category__in=list_of_your_category_ids,
state__code__in=list_of_your_category_names
)
这将为您提供所需的查询集。现在你需要做的就是用它们的类别重新组合这个查询集。
Django 提供了一个 regroup 模板标签来做这件事。
{% regroup queryset by category as categories_list %}
<ul>
{% for category in categories_list %}
<li>
{{category.grouper}}
<ul>
{% for item in category.list %}
<li>
{{item}}: state - {{item.state.code}}
</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
https://i.stack.imgur.com/TbTpz.png