2012-07-18 57 views
0

给定一个产品(product_name是视图中的一个参数),我试图返回该类别中的5个排名最高的产品(由方法“get_avg_rating”定义)作为我可以在模板中循环的列表。有关如何做到这一点的任何建议?如何获得某个类别中排名最高的产品?

class Productbackup(models.Model): 
    website = models.CharField('Product name', max_length = 200) 
    url_friendly = models.CharField('URL friendly', max_length = 200) 
    website_url = models.URLField('Product URL') 
    description= models.CharField('Description', max_length = 2000) 
    category = models.ForeignKey(Categories) 
    #category = models.ManyToManyField(Categories) 
    image_hero = models.URLField('Hero image url') 
    image_second = models.URLField('Second image url') 
    image_third = models.URLField('Third image url') 
    created_on = models.DateTimeField(auto_now_add = True) 
    updated_at = models.DateTimeField(auto_now = True) 
    def __unicode__(self): 
     return self.website 

    def get_avg_rating(self): 
     reviews = Reviewbackup.objects.filter(product=self) 
     count = len(reviews) 
     sum = 0.0 
     for rvw in reviews: 
      sum += rvw.rating 
     return (sum/count) 

    def get_num_reviews(self): 
     reviews = Reviewbackup.objects.filter(product=self) 
     count = len(reviews) 
     return count 

RATING_OPTIONS = (
    (1, '1'), 
    (2, '2'), 
    (3, '3'), 
    (4, '4'), 
    (5, '5'), 
       (6, '6'), 
    (7, '7'), 
    (8, '8'), 
    (9, '9'), 
    (10, '10'), 
) 
class Reviewbackup(models.Model): 
    review = models.CharField('Review', max_length = 2000) 
    created_on = models.DateTimeField(auto_now_add = True) 
    updated_at = models.DateTimeField(auto_now = True) 
    user = models.CharField('Username', max_length = 200) 
    rating = models.IntegerField(max_length=2, choices=RATING_OPTIONS) 
    product = models.ForeignKey(Productbackup) 
    def __unicode__(self): 
     return self.review 

class Categories(models.Model): 
    category = models.CharField('Category_second', max_length = 200) 
     url_friendly = models.CharField('url_friendly', max_length = 200) 
    def __unicode__(self): 
     return unicode(self.category) 

def view_reviews(request, product_name): 
    product = get_object_or_404(Productbackup, url_friendly=product_name) 
    product_id = product.id 
    #get reviews for the this product 
    reviews = Reviewbackup.objects.filter(product_id=product_id).order_by("-created_on") 
    #similar products in category comparison 
    prod_category = Productbackup.objects.filter(category=product.category) 
    #top_ranked = Productbackup.objects.order_by('get_avg_rating')[0:5] 
    #recently added 
    recent_added = Productbackup.objects.order_by('-created_on')[0:5] 
    return render_to_response('reserve/templates/view_reviews.html', {'prod_category': prod_category, 'product':product, 'reviews':reviews, 'recent_added':recent_added}, 
    context_instance=RequestContext(request)) 

回答

0

您可以使用annotate

from django.db.models import Sum, Avg 

def get_top_products(amount=5): 
    try: 
     Productbackup.objects.annotate(review_amount=Sum("reviewbackup__product")).\ 
           order_by("review_amount")[:amount] 
    except Productbackup.DoesNotExist: 
     return None 

这只是一个简单的例子,它可以扩展您的需求

0

试图实现:

创建字典。它将以产品为关键,评分为价值。

遍历您的项目(Product.objects

在这种循环中,把每个项目在字典

的是循环的,按值排序的字典。 (见Sort a Python dictionary by value

获取词典的最后一项(dictionary[-5])。

请注意,您将必须处理具有前“aequo评级的项目。事实上,如果10个项目具有相同的分数,那么使用上述方法,您的前5名并不意味着任何意义。

这将导致类似于下面的代码:

items_with_rating = {} 
for product in Product.objects: 
    items_with_rating[product] = product.get_avg_rating() 

items_sorted_by_rating = sorted(items_with_rating.iteritems(), key=operator.itemgetter(1)) 

top5_items = items_sorted_by_rating[-5] 
+0

我发现这个解决方案的问题是排序的字典(top5_items)不允许我访问产品的其他属性,如描述和类别。它只会返回一个包含产品名称和评级的字典。有关如何访问模板中的其他属性的任何想法? – sharataka 2012-07-21 19:19:19

+0

我不想粗鲁,但问题是,在使用Django之前,您需要学习Python语言的基础知识。字典键是你的产品OBJECTS,而不是字符串。顺便说一句,你应该选择更好的类名。 – tiktak 2012-07-23 06:24:09

0

也许这样的事情可以工作?

products = [[prod, prod.get_avg_rating()] for prod in Productbackup.objects()] 

top_5_items = sorted(products, key=lambda x: x[1], reverse=True)[:5] 
+0

你不只是重写/总结我的答案? – tiktak 2012-07-23 06:24:36

+0

那么有多种方法可以解决这个问题,我的代码行数很少,尽管结果是一样的。 – Mikael 2012-07-23 07:42:47

相关问题