2017-09-26 1 views
1

J'ai une liste d'éléments qui ont une «catégorie supérieure» et une «catégorie intermédiaire», éventuellement il y aura une «catégorie inférieure», mais pas tout de suite. Par exemple Électronique> Ordinateurs portables, respectivement.Django sous-catégories de facettes via des clés étrangères

Je veux dynamiquement facette de cette catégorie, donc les ordinateurs portables manifesterai sous l'électronique, etc.

Toute réflexion sur la façon dont je peux acheive cela? Actuellement, j'ai la facette "Top Catégories" correctement.

models.py

class mid_category(models.Model): 
    class Meta: 
     verbose_name_plural = 'Mid Categories' 
    name = models.CharField(max_length=500) 

    def __str__(self): 
     return self.name 

class top_category(models.Model): 
    class Meta: 
     verbose_name_plural = 'Top Categories' 

    name = models.CharField(max_length=500) 
    mid_cat = models.ForeignKey(mid_category, null=True) 

    def __str__(self): 
     return self.name 


# Item 
class Product(models.Model): 
    title = models.CharField(max_length=500, db_index=True) 
    price = models.DecimalField(max_digits=10, decimal_places=2) 
    retailer = models.CharField(max_length=255) 
    image = models.CharField(max_length=1000) 
    url = models.URLField(max_length=800, unique=True, default='') 
    sku = models.BigIntegerField(default=0) 
    barcode = models.BigIntegerField(default=0) 

    featured = models.CharField(max_length=255, db_index=True, choices=FEATURED_CHOICES, default='NO') 
    timestamp = models.DateTimeField(auto_now=True) 

    top_cat = models.ForeignKey(top_category) 
    mid_cat = models.ForeignKey(mid_category, null=True) 

    def __str__(self): 
     return self.title 

search_indexes.py

import datetime 
from django.utils import timezone 
from haystack import indexes 
from haystack.fields import CharField 

from decimal import Decimal 

from .models import Product, top_category 

class ProductIndex(indexes.SearchIndex, indexes.Indexable): 
    text = indexes.EdgeNgramField(
     document=True, use_template=True, 
     template_name='/home/wilkinj33/bargainforest/bargainforestenv/motorclass/templates/search/indexes/product_text.txt' 
     ) 

    title = indexes.EdgeNgramField(model_attr='title') 
    retailer = indexes.CharField(model_attr='retailer', faceted=True) 
    price = indexes.IntegerField(model_attr='price', faceted=True) 
    barcode = indexes.CharField(model_attr='barcode') 
    topCat = indexes.CharField(model_attr='top_cat', faceted=True) 
    midCat = indexes.CharField(model_attr='mid_cat', faceted=True) 

    def get_model(self): 
     return Product 

    def index_queryset(self, using=None): 
     """Used when the entire index for model is updated.""" 
     return self.get_model().objects.filter(timestamp__lte=timezone.now()) 

results.html

  <h3 class="widget-title">Shop Categories</h3> 
      <ul> 
      {% if facets.fields.topCat %} 
       {% for top_category in facets.fields.topCat %} 
       <li class="has-children"><a href="#" onclick="return onFacetChangeApplied();">{{top_category.0|cut:" "}}</a><span>(1138)</span> 
       <ul> 


       </ul> 
       </li> 
       {% endfor %} 
       {% endif %} 

Répondre

1

Il semble un peu bizarre de structurer vos modèles de cette façon.

Dans votre code actuel, vous semblez faire fausse route. Au lieu de la catégorie du milieu référençant son parent, la catégorie supérieure essaie de référencer ses enfants, ce qui est impossible car une clé étrangère ne peut pointer que sur un objet.

Si vous voulez faire dans votre code actuel, vous besoin de quelque chose plus comme ceci:

class TopCategory(models.Model): 
    name = ... 

class MiddleCategory(models.Model): 
    name = ... 
    parent = models.ForeignKey(TopCategory) 

mieux serait encore quelque chose de plus générique, comme cette structure d'arbre, capable de gérer un certain nombre de niveaux de Catégories:

class Category(models.Model): 
    name = ... 
    parent = models.ForeignKey('self', null=True, blank=True) 

vous pouvez ensuite filtrer sur une catégorie parente quelque chose comme:

`Product.objects.filter(category__parent=top_category) 

en supposant que vous avez un modèle Product avec un FK à Category.

Encore mieux, vous devriez probablement utiliser quelque chose comme django-mptt ou django-treebeard pour rendre votre arbre plus efficace.

+0

Merci Tom. Je vais lire sur la conception des modèles et les régler. Des idées sur le facettage? – Jack

+0

http://django-haystack.readthedocs.io/fr/v2.4.1/faceting.html pourrait être utile. –

+0

Merci, j'ai changé mes modèles et ils vont beaucoup mieux. Toujours pas de chance sur le front de facettage, j'ai passé les docs aussi. – Jack