Skip to content

Have support for __all__ fields and excludeΒ #33

@keystroke3

Description

@keystroke3

Problem

The current behavior does not have support for __all__ in fields parameter in an AdvancedFilterSet class. If a the fields parameter is set as

fields = '__all__'

without any filter_fields parameter will result in no model fields being added as arguments in the api. Given a model like this:

class Event(models.Model):
    STATUS = (
        ("Scheduled", "Scheduled"),
        ("Cancelled", "Cancelled"),
        ("Complete", "Complete"),
    )
    location = models.ForeignKey(
        Location, on_delete=models.SET_NULL, null=True, related_name="event_location"
    )
    photographer = models.ForeignKey(
        Photographer,
        on_delete=models.SET_NULL,
        null=True,
        related_name="event_photographer",
    )
    event_date = models.DateField()
    status = models.CharField(max_length=15, choices=STATUS, default="Scheduled")
    created = models.DateTimeField(auto_now_add=True)

If all the fields have to be included as possible filter fields, each of them would have to be specified in the filter class. So would all the other additional filter fields eg. photographer__name, photographer__email, event_date__year etc.
This issue is related to this comment graphql-python/graphene-django#1314 (comment) I made on an issue I raised on the graphene repo. There could also be a relationship with issue #29 on this repo.

Proposed Solution

Add support for __all__ fields and pass any queries on those fields back to django_filters.FilterSet. Then capture any extra fields specified in filter_fields from a field like extra_filters array in the query. This would allow all the fields described in the models to be accessible via the api and allow for extra filter rules to be specified and executed through AdvancedFilters like so:

allEvents(
    eventDate: 2022-5-2,
    status: "Cancelled",
    extra_filters: {
        photographer_FirstName: "John",
        location_Name: "Berlin",
        }
){ ... return fields ... }

A query like this would allow the client to get very specific with the filters and get exactly what they want. In the above example, it would be all cancelled events previously scheduled for 2022-5-2 in Berlin by photographers whose first name is John. To reduce verbosity spoken of in the graphene comment linked above, the filter field can be do exact matching by default especially, but if contains is specified, then it can do partial matching. That way, we don't have to keep specifying {exact: "search term"} for every field we are filtering against. So in the above example query, all the extra_filters are assumed to be exact matches. Something like this comes to mind:

    extra_filters: {
        photographer_FirstName_Contains: "John",
        ...
    }

or as currently implemented:

    extra_filters: {
        photographer_FirstName: {contains: "John"},
        ...
    }

These should match with photographers with first name John and Johnathan.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions