Python 在主页中显示计数和顶级类别

Python 在主页中显示计数和顶级类别,python,django,python-3.x,django-models,django-views,Python,Django,Python 3.x,Django Models,Django Views,我想在主页上显示顶级类别。我编写了top_categories函数来列出产品数量最多的类别。但是我已经在产品模型中编写了这个函数。我不知道该在哪里写这封信。这是我的密码 class Category(models.Model): name = models.CharField(max_length=50) slug = models.SlugField(max_length=50, unique=True) class Product(models.Model): na

我想在主页上显示顶级类别。我编写了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_categories函数,或者我现在的方式很好?因为在主页中显示内容的工作是主视图的角色

我想我会这样做:

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\u top\u Category
,以便可以调用
Category.objects.get\u top\u 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

有些

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

# 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 %}
{%load popcategories%}
{%popular_categories作为categories_list%}
{类别中类别的%u列表%}
{%empty%}
还没有分类

{%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 %}
{%用于类别中的类别%}
类别名称:{{category.name}
总产品:{category.product_count}
{%endfor%}

@milan,这对你来说应该很好。请尝试一下,如果您遇到任何问题,请告诉我。谢谢您的解决方案,但它说米兰没有名为“产品”的字段,应该是
products
,而不是
product
,因为您使用了相关名称。我已经更新了我的答案。现在应该可以了。看一看。谢谢。它起作用了。你能给我一个主意,如果我必须在模型中做逻辑,我应该如何在模板中显示它?我听说视图应该很小,但我认为这种类型的事情不应该在models.py中完成,它变得很乏味,因为它是面向结果的事情,应该在视图中处理,因为在模型中执行它,您需要覆盖模型管理器,这是一件乏味的事情。感谢您的解决方案。很抱歉,这一次我无法很好地连接top_类别和top_产品和视图。