简体   繁体   English

跨越多模型关系的Django树查询

[英]Django tree query spanning multi model relation

Please consider code the following code. 请考虑以下代码。 I'd like to create something like a tree structure (it will be in a table) related to a specific loged-in user. 我想创建类似于树形结构(将在表中)的某个特定登录用户。 I'd like to have an overviewpage in which all categories are shown for which this user has items in the subcategories. 我想要一个概述页面,其中显示了该用户在子类别中具有项目的所有类别。 My query works, but gives me all subcategory records and all posible items in those subcategories (so not just the subset for which the user has records. 我的查询有效,但是为我提供了所有子类别记录和这些子类别中的所有可能项目(因此,不仅是用户拥有记录的子集。

I have another way working by starting with the itemmodel and then going up in the tree, but thats not what i'm looking for (this makes creating a dynamic set of tables far to depended on the django template layer). 我还有另一种工作方式,从itemmodel开始,然后进入树状结构,但这不是我要的内容(这使得创建动态表集的方式远远取决于Django模板层)。

I've looked at select_related and prefetch, but I can't get close to a solution. 我已经看过select_related和prefetch,但是我无法找到一个解决方案。 Any help would be appriciated. 任何帮助将被申请。

models.py: models.py:

from django.db import models
from model_utils.models import TimeStampedModel
from django.conf import settings


User = settings.AUTH_USER_MODEL

class MainCat(TimeStampedModel):
    name = models.CharField(max_length=100, unique=True)
    rank = models.IntegerField(default=10)
    icon_class = models.CharField(max_length=100, null=True, blank=True)


class SubCat(TimeStampedModel):
    name = models.CharField(max_length=100, null=False, blank=False)
    slug = models.SlugField(null=True, blank=True)
    icon_class = models.CharField(max_length=100, null=True, blank=True)
    main_cat = models.ForeignKey(MainCat)


class Item(TimeStampedModel):
    user = models.ForeignKey(User, blank=True, null=True)
    item_name = models.CharField(max_length=100, null=False, blank=False)
    sub_cat = models.ForeignKey(SubCat, blank=True, null=True)

views.py: views.py:

from django.views.generic import ListView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import MainCat

class MainCatByUserListView(LoginRequiredMixin, ListView):
    model = MainCat
    def get_queryset(self):
        qs = super(MainCatByUserListView, self).get_queryset()
        qs = qs.filter(subcat__item__user=self.request.user)
    return qs

template: 模板:

< html >
< body >
{% for maincat in object_list %}
    < ul >
        <li> {{maincat.name}} </li>
        <ul>
        {% for subcat in maincat.subcat_set.all %}
            <li> {{subcat.name}} </li>
            {% for item in subcat.item_set.all %}
                <li> {{item.name}} </li>
            </ul>
        </ul>
        {% endfor %}
    {% endfor %}
{% endfor %}
< / body >
< / html >
{% endfor %}

您应该能够使用类似这样的东西: Subcat.objects.filter(item_set__user=self.request.user).select_related('main_cat')

Finaly got to an answer to my question. 菲纳丽回答了我的问题。 For future reference: 备查:

class MainCatListView(LoginRequiredMixin, ListView):
    model = MainCat
    template_name = 'app/main_cat_overview.html'

    def get_queryset(self):
        qs = super(MainCatListView, self).get_queryset()
        qs_user_cat_set = SubCat.objects.filter(item__user=self.request.user).prefetch_related(Prefetch(
            "item_set",
        queryset=Item.objects.filter(user=self.request.user),
        to_attr="item_attr")
            ).distinct()
        qs = qs.filter(subcat__item__user=self.request.user).prefetch_related(Prefetch(
            "subcat_set",
            queryset=qs_user_subcat_set,
            to_attr="subcat_attr")
                ).distinct()
        return qs

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM