Python 在主页中显示计数和顶级类别
我想在主页上显示顶级类别。我编写了top_categories函数来列出产品数量最多的类别。但是我已经在产品模型中编写了这个函数。我不知道该在哪里写这封信。这是我的密码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
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_产品和视图。