Input of type date required when filtering using double underscore day, month, or year in date fields.
Current behavior
Given a node like this:
class EventNode(DjangoObjectType):
class Meta:
model = Event
filter_fields = {
"event_date": ["exact", "year", "month", "day"],
"status": ["exact"],
}
interfaces = (relay.Node,)
and a query structure like this:
query filterEvents{
allEvents(){
edges{
node{
id
eventDate
}
}
}
}
In order to perform a filter for all events in the year 2022, I tried the following:
allEvents(eventDate_Year:"2022")
> "message": "['{\"event_date__year\": [{\"message\": \"Enter a number.\", \"code\": \"invalid\"}]}']",
allEvents(eventDate_Year:2022)
> "message": "Argument \"eventDate_Year\" has invalid value 2022.\nExpected type \"Date\", found 2022.",
allEvents(eventDate_Year:"2022-02-14")
> "message": "['{\"event_date__year\": [{\"message\": \"Enter a number.\", \"code\": \"invalid\"}]}']",
allEvents(eventDate_Year:"+2022")
> "message": "ISO 8601 extended year representation not supported."
I tried using django_filters but the field eventDate_Year ,eventDate_Month and eventDate_Day arguments where missing in the resulting api.
class EventFilter(django_filters.FilterSet):
class Meta:
model = Event
fields = "__all__"
filter_fields = {
"event_date": [ "exact","year","month", "day" ],
"status": ["exact"],
}
class EventNode(DjangoObjectType):
class Meta:
model = Event
filterset_class = EventFilter
interfaces = (relay.Node,)
Expected Behavior
I was expecting a eventDate_Year to behave like the django double underscore fields queries, e.g. date__year and take either a string or number as input, e.g.
Model.objects.filter(date_field__year="2022")
It is not possible to pass year only as a valid date.
What is the motivation / use case for changing the behavior? I would like to be able to filter a large data set by time period. So if only data from April 2022 is required, that is what is asked for. It doesn't seem very efficient to explicitly declare the same filters for every date field in every node, instead of specifying in the filter fields. Specifying a from-to date filter might be a viable solution, but it wouldn't work if data for say the 5th of every month in 2022 is required.
Please tell us about your environment:
- Version: 2.15.0
- Platform:
- Local: Arch Linux 5.16.13-arch1-1
- Remotes: Ubuntu 20.04
Other information I am not sure if this is a bug or a problem with my implementation. Before creating this issue, I asked on stack overflow, but got no response.
Use this filter https://github.com/devind-team/graphene-django-filter. I hope this helps you.
@Luferov ,thank you for the suggestion. I tried using it, but I find it quite verbose both on serverside and client side. I was trying to avoid this verbosity that comes with manually defining filterfields for date fields:
event_date__year = graphene_django_filter.NumberFilter(
field_name="event_date", lookup_expr="year"
)
event_date__month = graphene_django_filter.NumberFilter(
field_name="event_date", lookup_expr="month"
)
event_date__day = graphene_django_filter.NumberFilter(
field_name="event_date", lookup_expr="day"
)
exclude option and '__all__' option for fields don't seem to work. I have to manually define all the fields I want included with the fields dict. Having the fields variable set to '__all__' and adding a filter_fields variable in the filter class and placing all the filter fields there as specified in the graphene-django-filter docs leads to no fields being available in the resulting api. The frontend also has to use the verbose syntax:
node(
filter:{
field:{exact: 'search term'}
}
)
for every field they want to filter. In my ideal world, it would be
node(event_date_Year: 2022, field2:'filter term', filter:{<some complex filter here>})
I may be using the tool wrong, or may not know the advanced uses for it. The default filtering in graphene-django is fine for me. It's just the time fields that are the problem. They ask for integers and when you give the integer, they complains it is not a date type.
@Luferov ,thank you for the suggestion. I tried using it, but I find it quite verbose both on serverside and client side. I was trying to avoid this verbosity that comes with manually defining filterfields for date fields:
event_date__year = graphene_django_filter.NumberFilter( field_name="event_date", lookup_expr="year" ) event_date__month = graphene_django_filter.NumberFilter( field_name="event_date", lookup_expr="month" ) event_date__day = graphene_django_filter.NumberFilter( field_name="event_date", lookup_expr="day" )
excludeoption and'__all__'option forfieldsdon't seem to work. I have to manually define all the fields I want included with thefieldsdict. Having thefieldsvariable set to'__all__'and adding afilter_fieldsvariable in the filter class and placing all the filter fields there as specified in the graphene-django-filter docs leads to no fields being available in the resulting api. The frontend also has to use the verbose syntax:node( filter:{ field:{exact: 'search term'} } )for every field they want to filter. In my ideal world, it would be
node(event_date_Year: 2022, field2:'filter term', filter:{<some complex filter here>})I may be using the tool wrong, or may not know the advanced uses for it. The default filtering in graphene-django is fine for me. It's just the time fields that are the problem. They ask for integers and when you give the integer, they complains it is not a date type.
No problem, you can create an issue and we develop this feature. We use this library for your tasks and want to do this library greatest.