Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using filters with model inheritance

I have used Django Filters successfully before to filter models like so:

class ProductFilter(django_filters.FilterSet):
    minCost = django_filters.NumberFilter(name="cost", lookup_type='gte')
    maxCost = django_filters.NumberFilter(name="cost", lookup_type='lte')
    class Meta:
        model = Product
        fields = ['name', 'minPrice', 'maxPrice', 'manufacturer',]

Now I want to use a Django Filter to filter between many different models which all inherit from a base model, for example (my models are not this simple but to illustrate the point):

class BaseProduct(models.Model):
    name = models.CharField(max_length=256)
    cost = models.DecimalField(max_digits=10,decimal_places=2)

class FoodProduct(BaseProduct):
    farmer = models.CharField(max_length=256)

class ClothingProduct(BaseProduct):
    size = models.CharField(max_length=256)

Is there a way to use a Django filter that would work with all models that inherit from BaseProduct? In my case there would be a large number of models some with a large number of variables.

like image 374
Dawson Avatar asked Feb 27 '26 11:02

Dawson


1 Answers

Add to your BaseProduct

 class Meta:
    abstract = True

https://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes

Base model will not be used to create any database table. Instead, when it is used as a base class for other models, its fields will be added to those of the child class.

https://django-filter.readthedocs.io/en/stable/guide/usage.html#the-filter

Just like with a ModelForm we can also override filters, or add new ones using a declarative syntax

class BaseProductFilter(django_filters.FilterSet):
    name = django_filters.CharFilter(lookup_type='icontains')
    cost = django_filters.NumberFilter(lookup_type='lt')
    

class FoodProductFilter(BaseProductFilter):
    farmer = django_filters.CharFilter(lookup_type='icontains')
    
    class Meta:
        model = FoodProduct
        fields = ['name', 'cost', 'farmer']


class ClothingProductFilter(BaseProductFilter):
    # size lookup_type will be 'exact'
    class Meta:
        model = ClothingProduct
        fields = ['name', 'cost', 'size']
like image 92
madzohan Avatar answered Mar 01 '26 08:03

madzohan