How to add to crispy filter field from different model?

I need help with adding field from different model to my crispy filter.

I have a model Warehouse with product and pieces and filter based on product name. I have a model Product with name, pyear and category and I was able to add pyear to filter and it is working.

And finally I have a model Category with category_name and I would like to add category name to filter. I try to add category field to filter as category__category_name or through product table as below product__category__category_name, but category field is not visible in html template and I am getting following error:

KeyError: "Key 'category' not found in 'WarehouseDataFilterForm'. Choices are: pieces, product, pyear."

And my question is how can I add category_name to my filter? So the category field will be visible in template and I will be able to filter my data by category.

Models:

class Category(models.Model):
    category_name = models.CharField("Category", max_length=100, blank=True, null=True)

class Product(models.Model):
    name = models.CharField("Product", max_length=150)
    pyear = models.IntegerField("Production Year", null=True, blank=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True)

class Warehouse(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, null=True, blank=True)
    pieces = models.IntegerField("Quantity", null=True, blank=True)

Filter:

class WarehouseDataFilterFormHelper(FormHelper):
    form_method = 'GET'
    layout = Layout(
            Div(
                Div("product", css_class="col-12 col-sm-8 col-md-5"),
                Div("category", css_class="col-8 col-sm-4 col-md-2"),
                Div("pyear", css_class="col-4 col-sm-3 col-md-2"),
                Div(Submit('submit', 'Filter', css_class='btn btn-dark'), css_class="col-2 col-md-1 block my-auto align-bottom text-center"),
                Div(HTML('<a href="/warehouse/warehouse_data" class="orange"><i class="fa-regular fa-trash-can"></i> Clear</a>'), css_class="col-2 text-center block my-auto align-bottom"),
                css_class="row"
            ),
        )


class WarehouseDataFilter(django_filters.FilterSet):

    product = django_filters.CharFilter(label="Produkt", field_name="product__name", lookup_expr='icontains')
    category = django_filters.CharFilter(label="Kategorie", field_name="product__category__category_name", lookup_expr="icontains" ),
    pyear = django_filters.NumberFilter(label="Rok výroby", field_name="product__pyear")

    class Meta:
        model = Warehouse
        fields = ("product", "pieces")
        attrs={"a": {"class": "orange"}, "thead": {"class": "orange"}}
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.form.helper = WarehouseDataFilterFormHelper()


Views:

class WarehouseDataView(LoginRequiredMixin, FilterView):
    template_name = "warehouse/warehouse_data.html"
    model = Warehouse
    filterset_class = WarehouseDataFilter


    def get_filterset(self, filterset_class):
        filterset = super().get_filterset(filterset_class)
        filterset.form.helper = WarehouseDataFilterFormHelper()
        return filterset

  
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        inventory_data = self.object_list.values().order_by("product")


        try:
            updated = Warehouse.objects.values("updated_on").last()
        except:
            updated = 0
        
        context["updated"] = updated


        try:
            wtable = utils.warehouse_data_creation(inventory_data)
        except:
            wtable = 0
        
        context["wtable"] = wtable


        try:
            warehouse_dict = utils.warehouse_dict_summary(wtable)
        except:
            warehouse_dict = 0
        
        context["warehouse_dict"] = warehouse_dict


        return context

Thanks a lot for help.

Back to Top