以多对多关系对相关集进行排序

时间:2014-02-10 21:10:10

标签: django django-models many-to-many django-orm

假设我有这样的设置:

class Product(models.Model):
    name = models.CharField()
    category = models.CharField()

class Shop(models.Model):
    name = models.CharField()
    website = models.URLField()

class ProductPrices(model.Model):
    product = models.ForeignKey(Product)
    shop = models.ForeignKey(Shop)
    price = models.FloatField()
    updated = models.DateTimeField()

然后我有一个页面,我想列出所有产品,可以找到哪些商店以及价格。是否可以对所有(或仅部分)产品的价格进行分类,而不使用:

class Meta:
    ordering = ['-price']

ProductPrices

也就是说,在我看来,我想做这样的事情(在价格栏上对productprice_set进行排序):

def get_queryset(self):
    queryset = Product.objects.all()
    for product in queryset:
        product.productprice_set.order_by('-price')
        # Have also tried the following, without any result
        product.productprice_set = product.productprice_set.order_by('-price')
return queryset

澄清:我想对每种产品的价格进行排序,而不是根据价格对产品进行分类。但我想通过“通过”产品的方式来做到这一点。 我想订购'productprice_set',而不是'产品'。

2 个答案:

答案 0 :(得分:0)

该语法不会以某种方式修改关系,以便后续调用返回有序的查询集:它然后返回有序的qs。后续调用将具有默认顺序。

执行此操作的方法是在检索对象时使用order_by子句。由于您无法将参数传递给模板中的方法,因此可以在Product上定义一个返回订购价格的方法:

class Product(models.Model):
    ...
    def ordered_prices (self):
        return self.productprices_set.order_by('-price')

并在模板中调用它:

{% for product in products %}
    {{ product.name }}
    {% for price in product.ordered_prices %}
        {% price.price %}
    {% endfor %}
{% endfor %}

答案 1 :(得分:0)

我现在找到了一个解决方案,我不需要修改任何模型,也不需要再进行数据库查询。

在我看来,我现在有:

def get_queryset(self):
    queryset = Product.objects.all().prefetch_related('price_set')

    for product in queryset:
        product.prices = sorted(product.price_set.all(), key=lambda x: x.price, reverse=true)

return queryset

然后在我的模板中:

{% for product in products %}
    {{ product.name }}
    {% for price in product.prices %}
        {% price.price %}
    {% endfor %}
{% endfor %}

由于我刚开始使用Django,我想知道是否有任何“错误”或“坏”通过像这样解决它?