通过反向外键进行 Django 过滤器过滤

时间:2021-04-06 12:13:23

标签: django django-filter

我有 3 个模型:Product、Action、ActionProduct。

class Product (models.Model):
     p = models.CharField()

class Action(models.Model):
     a = ... 
     <a lot more fields>
    
class ActionProduct(models.Model):
    product = ForeignKey(ProductList)
    action = ForeignKey(Action)

我的目标是能够按产品过滤操作模型。

它适用于其他字段和外键,如类别、作者等:

category = django_filters.ModelMultipleChoiceFilter(
    queryset=CategorySocial.objects.all() 
)

但是如何通过反向外键进行过滤?

当使用 django-filters 并希望按产品过滤 Action 模型时,挑战就来了。 我试图通过过滤 ActionProduct 模型来重新排列。它几乎有效。但是最近添加了产品模型,并不是所有的动作都选择了产品,所以没有产品的动作会丢失。

你能指导我一些方向吗?

1 个答案:

答案 0 :(得分:2)

ManyToManyField 只会隐式地创建一个类似于您创建的 ActionProduct 模型的模型。由于您已经制作了此模型,因此只需将其指定为 ManyToManyFieldthrough model [Django docs]。通过这种方式,您可以更轻松地进行查询,然后可以轻松地进行过滤:

class Action(models.Model):
     a = ... 
     products = models.ManyToManyField(
         Product,
         through='ActionProduct',
         related_name='actions'
     )
     <a lot more fields>

现在运行 python manage.py makemigrationspython manage.py migrate,以便您的迁移文件反映这一点。

现在在您的过滤器集中,您可以简单地将 products 添加为 ModelMultipleChoiceFilter,因为它是您模型中的一个字段:

products = django_filters.ModelMultipleChoiceFilter(
    queryset=Product.objects.all() 
)

或者简单地将其添加到过滤器集的 fields 中的 Meta 属性:

class SomeFilter(django_filters.FilterSet):
    class Meta:
        model = Action
        fields = ['products', ...]