Django w / django_filters通过方法或非模型字段进行查找

问题描述

版本:Django 3.0.6,Python 3.8,MysqL 8.0,django_filters 2.3.0

请多多包涵,因为我不确定我是否正确题名。我将从相关代码开始:

models.py

class vendor(models.Model):
    name = models.CharField(max_length=50)
    
class Category(models.Model):
    name = models.CharField(max_length=50)
    
class Product(models.Model):
    name = models.CharField(max_length=50)
    vendor = models.ForeignKey('vendor',on_delete=models.SET_NULL,null=True)
    category = models.ForeignKey('Category',null=True)
    
class rating (models.Model):
    score = models.PositiveIntegerField(default=0,validators=[MaxValueValidator(10)])
    product = models.ForeignKey('vendor',null=True)
    
    def category(self):
        return self.product.category
        
    def vendor(self):
        return self.product.vendor

filters.py

from .models import vendor,Category,Product,rating
import django_filters

class ratingFilter(django_filters.FilterSet):
    rating_filter = django_filters.RAngeFilter(field_name='score',lookup_expr='range')
    
    class Meta:
        model = rating
        fields = '__all__'

views.py

from .filters import ratingFilter

def ratingSearch(request):
    rating_list=rating.objects.all()
    rating_filter = ratingFilter(request.GET,queryset=rating_list)
    return render (request,'inventory/rating_search.html',{ 'filter': rating_filter})

从基本的sql角度来看,我知道我可以将模型用作大纲,并通过建立表之间的关系来按类别或供应商筛选对评级记录的搜索。我的目标是使用django_filters在Web表单上执行相同的操作。

开箱即用,按产品和/或分数过滤评级非常容易。我似乎无法解决的问题是如何根据未在模型中直接引用的信息进行过滤。当我查看评级的详细视图时,无需执行任何特殊操作即可使类别方法{{ rating.category }}起作用。但是,过滤器类似乎更抽象一些,而文档通常使我无所适从。

我可以将类别和供应商字段复制到评级对象,但这感觉像黑客一样。我花了几个小时试图找到其他人在做类似的事情,但是我感到我没有用正确的术语进行搜索,或者我只是错过了一些显而易见的东西。

解决方法

来自documentation

field_name:要过滤的模型字段的名称。您可以使用Django的__语法遍历“关系路径”以过滤相关模型上的字段。例如manufacturer__name

看起来您基本上可以执行以下操作:

rating_filter = django_filters.RangeFilter(
    field_name='product__category',lookup_expr='range')