简体   繁体   中英

Django w/django_filters lookups by methods or non-model fields

Versions: Django 3.0.6, Python 3.8, MySQL 8.0, django_filters 2.3.0

Please bear with me as I am not sure if I have entitled the question properly. I will start with the relevant code:

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', on_delete=models.SET_NULL, null=True)
    
class Rating (models.Model):
    score = models.PositiveIntegerField(default=0, validators=[MaxValueValidator(10)])
    product = models.ForeignKey('Vendor', on_delete=models.SET_NULL, 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})

From a basic SQL perspective, I know that I can use the models as outline and filter a search of Rating records by a Category or Vendor by establishing the relationships between the tables. My goal is to use django_filters to do the same thing on a web form.

Out of the box it is super easy to filter Ratings by Product and/or the Score. What I can't seem to sort out is how I can filter by a piece of information that isn't directly referenced off the model. When I do a detail view of the Rating, I don't have to do anything special to get the category method {{ rating.category }} does the job. However, the filter class seems to be a bit more abstract and the documentation just leaves me scratching my head most of the time.

I could replicate the category and vendor fields to the rating object, but that feels like hackery all around. I've spent several hours trying to find someone else doing something similar, but I have a feeling that I'm not searching with the right terminology or I'm just missing something blindingly obvious.

From the documentation :

field_name : The name of the model field to filter on. You can traverse “relationship paths” using Django's __ syntax to filter fields on a related model. ex, manufacturer__name .

So it looks like you can basically do the following:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM