【问题标题】:Django: Organize objects in a dictionary by foreign keyDjango:通过外键组织字典中的对象
【发布时间】:2016-10-06 02:50:06
【问题描述】:

我有这个问题:我有两个模型,产品和类别,类别定义在一个夹具中(它们不会改变),我需要在一个模板中显示所有类别,作为一个网格。模型比较简单,重要的是 Products 有一个外键指向 Category 模型,还有一个外键指向 User 模型(所有者)。

我必须在每个类别块中显示所有产品(CSS 无关紧要,我只需要能够将它们显示出来)但我目前得到的解决方案是这样的

查看

def index(request):
    user_products = []
    if request.user.is_authenticated():
        user_products = Product.objects.filter(owner=request.user)
    categories = Category.objects.all()
    return render(request, 'index.html', {'user_products': user_products, 'categories': categories})

模板

<!-- This goes for each category, 12 in total -->
<div>
    <h3>Category (name hardcoded)</h3>
    {% for category in categories %}
        {% if category.pk == 3 %}
            <ul class="product_list">
            {% for product in category.product_set.all %}
                {% if product.owner == request.user %}
                <li>
                    <div class="product">
                        <h2 class="title">{{ product.title }} </h2>
                        <p class="text">{{ product.text }}</p>
                    </div>
                </li>
                {% endif %}
            {% empty %}
            {% endfor %}
            </ul>
        {% endif %}
    {% endfor %}
</div>

我想在上下文中发送如下内容:

user_products = {<category.pk>: [list of Product objects in category]}

这样我就可以访问每个类别的产品列表,而无需每次定义 for 循环通过 request.user 过滤它们。你能想出更好的方法来做到这一点吗?我必须对每个类别进行硬编码,因为它们具有给定的顺序,但是如果您知道如何在保持该顺序的同时动态显示它们,那就太好了。谢谢!

【问题讨论】:

    标签: python django django-templates


    【解决方案1】:

    有更好的方法来做到这一点。使用Prefetch 对象。预取将只过滤每个类别的数据。

    from django.db.models.query import Prefetch
    
    def index(request):
        user_products = []
        if request.user.is_authenticated():
            user_products = Product.objects.filter(owner=request.user)
        else:
            # answering comment
            user_products = Product.objects.none()
        prefetch = Prefetch('product_set', queryset=user_products)
        categories = Category.objects.all().prefetch_related(prefetch)
    
        return render(request, 'index.html', {'categories': categories})
    

    然后你可以在模板中做到这一点

    <!-- You need to do this only once. No need to copy this for each category -->
    <div>
        {% for category in categories %}
        <h3>Category {{ category.name }}</h3>
            <ul class="product_list">
            {% for product in category.product_set.all %}
                <li>
                    <div class="product">
                        <h2 class="title">{{ product.title }} </h2>
                        <p class="text">{{ product.text }}</p>
                    </div>
                </li>
            {% endfor %}
            </ul>
        {% endfor %}
    </div>
    

    【讨论】:

    • 不错!硬编码的 HTML 是因为我必须给类别一个特定的顺序,但我想我可以在模型中添加一些东西。当用户未通过身份验证时,我想显示类别而不是产品,我如何使用 Prefetch 做到这一点?
    • @JuliánBonilla 尝试做Product.objects.none()。查看更新的答案
    猜你喜欢
    • 2014-01-08
    • 2017-01-28
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    相关资源
    最近更新 更多