如何获取每种产品类型的前两个产品?

时间:2009-08-31 13:29:15

标签: django django-models

假设我有两个模型:

class ProductType(models.Model):
    product_type = models.CharField(max_length=100)

class Product(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField()

    product_type = models.ForeignKey(ProductType)

    score = models.PositiveIntegerField(default=0)

现在我想从每个ProductType中获取前两个产品(两个得分最高的产品)。 因此,如果我有手机,电脑,电视作为ProductTypes,我想要两款最好的手机,电脑,电视。

由于我甚至不知道如何在MySQL中执行此操作,我尝试搜索MySQL解决方案,但我找到的解决方案非常复杂,这并不是一件非常复杂的事情。

我倾向于为顶级产品制作一个自己的模型,并有一个cronjob来解决这个问题,但我想看看是否有一个更简单的解决方案。

3 个答案:

答案 0 :(得分:5)

好吧,您可以在ProductType类中创建一个方法,该方法返回其产品的前两个结果:

class ProductType(models.Model):
    product_type = models.CharField(max_length=100)

    def TopTwoProducts(self):
        return self.product_set.order_by('-score')[0:2]

然后你会做类似的事情:

for type in ProductType.objects.all():
    type.TopTwoProducts()

答案 1 :(得分:4)

虽然亚当的解决方案是正确的,但更多的方法是使用经理。

请参阅James Bennett博客上的Managers versus class methods

其他优点:

  • 管理员携带所有特定于查询的代码,同时避免使模型类混乱
  • 同一个经理类可以在多个类之间共享
  • 经理可以直接在模型类上使用,也可以通过一对多或m2m关系使用

因此,对于上述问题:

from django.db import models
from django.db.models.manager import Manager

class ProductScoreManager(Manager):

    use_for_related_field = True

    def top_score(self, limit=2):
        return self.get_query_set().order_by('-score')[:limit]

然后将此经理类添加为Product:

默认管理器
class Product(models.Model):
    ...
    objects = ProductScoreManager()
    ...

现在,由于 objects 覆盖了默认管理器,而 use_for_related_field 允许在关系查询中使用它,top_score方法可以用在任何与产品相关的模型中。 / p>

myproducttype = ProductType.objects.get(...)
myproducttype.products.top_score() # return top 2 products

这允许更一致的语法:始终通过产品 top_score 作为过滤器访问相关产品。此外,ProductType类不再与Product的查询逻辑混杂在一起。

答案 2 :(得分:0)

只需从产品模型中过滤出产品类型,就可以像这样对它们进行切片-

A Flink cluster needs exactly as many task slots as the highest parallelism
used in the job. No need to calculate how many tasks (with varying parallelism)
a program contains in total.