You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django模板按分类分栏展示条目:如何实现分类内取前3后3项

Yes, This Is Totally Possible!

The issue with your initial approach was that you were slicing the global list of items instead of slicing the items per category. To fix this, we need to group items by their category first, then handle each category's item list individually. Here's how to do it step by step:

Step 1: Prepare Your Data in the View

First, make sure you're fetching categories along with their associated items efficiently (to avoid N+1 database queries). Use prefetch_related to load all items for each category in one go, and define an order for the items so your "first 3" and "last 3" make sense.

Assuming your models look like this:

# models.py
from django.db import models

class Category(models.Model):
    name = models.CharField(max_length=100)

class Item(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="items")
    name = models.CharField(max_length=100)
    # Add other fields as needed

Your view would look something like this:

# views.py
from django.shortcuts import render
from django.db.models import Prefetch
from .models import Category, Item

def category_items_view(request):
    # Fetch categories, prefetching items ordered by (for example) name or date
    categories = Category.objects.prefetch_related(
        Prefetch(
            "items",
            queryset=Item.objects.order_by("name")  # Adjust ordering to your needs
        )
    ).all()
    
    return render(request, "your_template.html", {"categories": categories})

Step 2: Render the Two Columns in the Template

Now in your Django template, create two columns (using flexbox, Bootstrap, or your preferred layout). For each column, loop through every category, then slice that category's item list to get the first 3 or last 3 items.

<!-- your_template.html -->
<div style="display: flex; gap: 2rem; padding: 1rem;">
    <!-- Column 1: First 3 items per category -->
    <div style="flex: 1;">
        <h2>Top 3 Items per Category</h2>
        {% for category in categories %}
            <h3>{{ category.name }}</h3>
            <ul>
                {% for item in category.items.all|slice:":3" %}
                    <li>{{ item.name }}</li>
                {% empty %}
                    <li>No items in this category.</li>
                {% endfor %}
            </ul>
        {% endfor %}
    </div>

    <!-- Column 2: Last 3 items per category -->
    <div style="flex: 1;">
        <h2>Last 3 Items per Category</h2>
        {% for category in categories %}
            <h3>{{ category.name }}</h3>
            <ul>
                {% for item in category.items.all|slice:"-3:" %}
                    <li>{{ item.name }}</li>
                {% empty %}
                    <li>No items in this category.</li>
                {% endfor %}
            </ul>
        {% endfor %}
    </div>
</div>

Key Notes:

  • Order Matters: Make sure your items are ordered correctly (e.g., by date, name, or priority) so the first/last 3 slices reflect what you want. Adjust the order_by in the view to match your needs.
  • Edge Cases: If a category has fewer than 3 items, the slice will just display all available items (the {% empty %} block handles categories with no items at all).
  • Efficiency: Using prefetch_related ensures we only make two database queries (one for categories, one for items) instead of one per category—critical for performance if you have many categories.

This approach ensures each category's items are split correctly between the two columns, exactly what you're looking for!

内容的提问来源于stack exchange,提问作者user9305920

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:30:28