在homepag中显示count和top\u类别

2024-05-19 22:47:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在主页上显示顶级类别。我编写了top_categories函数来列出拥有最多产品的类别。但是我已经在产品模型中编写了这个函数。我不知道该在哪里写这个。这是我的密码

class Category(models.Model):
    name = models.CharField(max_length=50)
    slug = models.SlugField(max_length=50, unique=True)

class Product(models.Model):
    name = models.CharField(max_length=200, unique=True,
                            blank=False, null=False)
    categories = models.ManyToManyField(Category, related_name='products')

    def top_categories(self):
        product = Product.objects.values('id').annotate(
            categories_count=models.Count('categories')).order_by('-categories_count')
        return product

def home(request):
    categories = Category.objects.all()
    companies = Company.objects.all()[:12]
    context = {
        'categories': categories,
        'companies': companies
    }
    return render(request, 'company/home.html', context)

现在有一个困惑,我是否必须在Category model中实现top\ u categories函数,或者我正在做的方式很好?因为在主页中显示内容的工作是主视图的角色


Tags: 函数namemodelobjects产品modelstop主页
3条回答

我建议您使用templatetags,因为如果您使用views处理这种情况,您将为另一个页面创建类似的流行过滤器

# yourapp/templatetags/popcategories.py

from django import template
from yourapp.models import (Category, Product)

register = template.Library()

@register.assignment_tag
def popular_categories():
    categories = Category.objects.all()
    get_total = lambda c: Product.objects.filter(categories__slug=c.slug).count()
    tags_list = [{'category': category, 'total': get_total(category)} for category in categories]
    tags_list.sort(key=lambda x: int(x['total']), reverse=True)
    return tags_list[:10] # return 10 top

然后,您可以在模板company/home.html中使用它

{% load popcategories %}
{% popular_categories as categories_list %}
{% for category in categories_list %}
  <a href="">
    {{ category.name }} - {{ category.slug }}
  </a>
{% empty %}
  <p>No categories yet!</p>
{% endfor %}

您可以在视图.py中执行此操作

def home(request):
    # arrange your category on basis of product_count
    categories = Category.objects.annotate(product_count = Count('products')).order_by('-product_count')
    # if you want only top 10 categories
    # categories = categories[:10]
    companies = Company.objects.all()[:12]
    context = {
        'categories': categories,
        'companies': companies
    }
    return render(request, 'company/home.html', context)

home.html中

{% for category in categories %} 
    <h3> category name:</h3>{{category.name}}
    <h3> Total product::</h3>{{category.product_count}}
{% endfor %}

我想我会这样做:

class Category(models.Model):
    name = models.CharField(max_length=50)
    slug = models.SlugField(max_length=50, unique=True)

    @staticmethod
    def top_category():
        return models.Count('categories')).order_by('-categories_count')

使其成为静态方法,因为它与实例无关。更好的方法是扩展Category manager并向其添加方法get_top_category,这样就可以调用Category.objects.get_top_category()。那就在你的产品模型里说吧:

   def top_products(self):
        count_category = Category.top_category() # or Category.objects.get_top_category() if you have done it this way
        product = Product.objects.values('id').annotate(count_category)
        return product

一些doc to override managers

相关问题 更多 >