首页 > 解决方案 > 如何根据其他非相关模型过滤django模型

问题描述

请参考下面的代码

交易模型

class Transaction(models.Model)
    current_product_code = models.CharField(....)
    previous_product_code = models.CharField(....)
    @property
    def status(self):
        c_price = Product.objects.get(code=self.current_product_code).price
        p_price = Product.objects.get(code=self.previous_product_code).price
        if c_price == p_price:
            return "Due"
        elif c_price > p_price:
            return "Upgrade"
        else:
            return "Downgrade"

产品型号

class Product(models.Model):
    code = models.CharField(....)
    price = models.DecimalField(....)

我的问题:如何获取/过滤具有升级/降级/到期状态的交易。我正在尝试创建一个自定义管理过滤器,该过滤器根据交易状态过滤交易,但我无法在 .filter() 中放入什么,请检查以下方法

def queryset(self, request, queryset):
    value = self.value()
    if value == 'Upgrade':
        return queryset.filter(***** HERE *****)
    elif value == 'Downgrade':
        return queryset.filter(***** HERE *****)
    elif value == 'Unknown':
        return queryset.filter(***** HERE *****)
        return queryset

标签: pythondjango

解决方案


你真的应该使用ForeignKeybetween Productand Transaction(for both: current_product_codeand previous_product_code)。这将允许您轻松地在查询集中使用这些关系。

我提出的模型结构如下所示:

class Product(models.Model):
    code = models.CharField(....)
    price = models.DecimalField(....)


class Transaction(models.Model)
    # You have to define related_name for at least one of relations below.
    # Without that, automatically generated ones will clash.
    # Also don't foget to change `on_delete` to suit your needs.
    current_product = models.ForeignKey(Product, related_name="current_transactions", on_delete=models.CASCADE)
    previous_product = models.ForeignKey(Product, related_name="previous_transactions", on_delete=models.CASCADE)

    @property
    def status(self):
        # also, no need to do additional queries here manually. You can improve
        # it further by using `select_related` when querying for transactions.
        c_price = self.current_product.price
        p_price = self.previous_product.price
        if c_price == p_price:
            return "Due"
        elif c_price > p_price:
            return "Upgrade"
        else:
            return "Downgrade"

使用该模型结构,查找特定类型的交易将更容易:

upgrade_transactions = Transaction.objects.filter(current_product__price__gt=F('previous_product__price'))
downgrade_transactions = Transaction.objects.filter(current_product__price__lt=F('previous_product__price'))
due_transactions = Transaction.objects.filter(current_product__price=F('previous_product__price'))

推荐阅读