2017-09-21 4 views
2

Je veux afficher les top_categories dans la page d'accueil. J'ai écrit la fonction top_categories pour lister les catégories qui ont le plus de produits. Mais j'ai écrit cette fonction dans Product Model. Je suis confus sur où devrais-je écrire ceci. Voici mon codeafficher le nombre et les catégories supérieures dans la page d'accueil

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) 

Maintenant, il y a une confusion, Dois-je mettre en œuvre la fonction de top_categories dans la catégorie modale ou la façon dont je fais est bien? Parce que le travail de montrer le contenu dans la page d'accueil est le rôle de la vue de la maison.

Répondre

1

Vous pouvez le faire dans views.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) 

Dans home.html

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

@milan, Cela devrait fonctionner correctement pour vous. Essayez-le et faites-moi savoir si vous rencontrez un problème. –

+0

Merci pour votre solution, mais il dit qu'il n'y a pas de champ appelé «produit» – milan

+0

@milan, Il devrait être 'products' au lieu de' product' coz de nom apparenté que vous avez utilisé. J'ai mis à jour ma réponse. Cela devrait fonctionner maintenant. Regarde. –

0

bien pense que je ferais quelque chose comme ceci:

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') 

ont rendu une méthode statique car il est pas une instance. Une meilleure façon de le faire serait d'étendre le gestionnaire de catégorie et d'y ajouter une méthode get_top_category afin que vous puissiez appeler un Category.objects.get_top_category(). Ensuite, il suffit d'appeler dans votre modèle de produit:

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 

Certains doc to override managers

+0

Merci pour la solution. Désolé, celui-ci, je ne pouvais pas bien se connecter entre top_category et top_products et vues. – milan

0

Je vous suggère d'utiliser templatetags, parce que si vous gérez ce cas avec views vous créerez filtre populaire pour une autre similaire page.

# 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 

Et puis, vous pouvez l'utiliser dans votre modèle avec 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 %}