class EnhancedQuerySet:
    """
    Extends the functionalities of Django QuerySet
    Example:
    - before:
    def some_function(
        fk1_ids: Optional[List[int]] = None,
        fk2_ids: Optional[List[int]] = None,
        fk3_ids: Optional[List[int]] = None,
        fk4_ids: Optional[List[int]] = None,
        pk_ids: Optional[List[int]] = None,
        ...
    ):
        some_instances_queryset = SomeModelClass.objects.all()
        if fk1_ids is not None:
            some_instances_queryset = some_instances_queryset.filter(fk1_id__in=fk1_ids)
        if fk2_ids is not None:
            some_instances_queryset = some_instances_queryset.filter(fk2_id__in=fk2_ids)
        if fk3_ids is not None:
            some_instances_queryset = some_instances_queryset.filter(fk3_id__in=fk3_ids)
        if fk4_ids is not None:
            some_instances_queryset = some_instances_queryset.filter(fk4_id__in=fk4_ids)
        if pk_ids is not None:
            some_instances_queryset = some_instances_queryset.filter(id__in=pk_ids)
        for some_instance in some_instances_queryset:
            ...
    - after:
    def some_function(
        fk1_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
        fk2_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
        fk3_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
        fk4_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
        pk_ids: Optional[List[int]] = EnhancedQuerySet.IGNORE_FILTER,
        ...
    ):
        some_instances_queryset = EnhancedQuerySet(SomeModelClass.objects.all())
        some_instances_queryset.filter(
            fk1_id__in=fk1_ids,
            fk2_id__in=fk2_ids,
            fk3_id__in=fk3_ids,
            fk4_id__in=fk4_ids,
            id__in=pk_ids,
        )
        for some_instance in some_instances_queryset.queryset:
            ...
    You may alias EnhancedQuerySet for shorter code :
    from ... import EnhancedQuerySet as EQS
    def some_function(
        fk1_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
        fk2_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
        fk3_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
        fk4_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
        pk_ids: Optional[List[int]] = EQS.IGNORE_FILTER,
        ...
    ):
        some_instances_queryset = EQS(SomeModelClass.objects.all())
        some_instances_queryset.filter(
            fk1_id__in=fk1_ids,
            fk2_id__in=fk2_ids,
            fk3_id__in=fk3_ids,
            fk4_id__in=fk4_ids,
            id__in=pk_ids,
        )
        for some_instance in some_instances_queryset.queryset:
            ...
    """
    IGNORE_FILTER = object() # a sentinel for ignoring some filter to distinguish from None
    
    def __init__(self, queryset):
        self.queryset = queryset
    
    def _get_true_kwargs(self, kwargs: dict):
        true_kw_args = {}
        for key, value in kwargs.items():
            if value is EnhancedQuerySet.IGNORE_FILTER:
                continue
        true_kw_args[key] = value
        return true_kw_args
    
    def filter(self, *args, **kwargs):
        """
        Enhanced filter function with 2 features :
        - ignore some filters given with some default value
        - never forget the affectation after filtering, i.e. avoid this mistake:
        queryset.filter()
        instead of queryset = queryset.filter()
        """
        true_kw_args = self._get_true_kwargs(kwargs)
        self.queryset = self.queryset.filter(*args, **true_kw_args)
    
    def exclude(self, *args, **kwargs):
        """
        Similar to filter method but with exclude
        """
        true_kw_args = self._get_true_kwargs(kwargs)
        self.queryset = self.queryset.exclude(*args, **true_kw_args)