1

I am building a django graphql api with graphene for photography events. Each event has a location, photographer and event date. I want to be able to filter all events by year, month or day, e.g. return all events happening in April 2022 or all events that happen on Thursdays. I would also like to filter for future events only. The model:

# models.py

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

    class Meta:
        constraints = [
            models.UniqueConstraint(
                name="location_event", fields=("location", "event_date")
            )
        ]

    def __str__(self):
        return f"Event {self.location}, {self.event_date}, {self.status}"
# schema.py

from graphene_django import DjangoObjectType
from graphene import relay, ObjectType
from graphene_django.filter import DjangoFilterConnectionField

from events.models import Event



class EventNode(DjangoObjectType):
    class Meta:
        model = Event
        filter_fields = {
            "event_date": ["exact", "year", "month", "day"],
            "status": ["exact"],
        }
        interfaces = (relay.Node,)

class EventsQuery(ObjectType):
    event = relay.Node.Field(EventNode)
    all_events = DjangoFilterConnectionField(EventNode)

Using this set up, when I try to run this query on graphiql browser interface:

query filterEvents{
  allEvents(eventDate:"2022-02-14"){
    edges{
      node{
        id
        eventDate
        photographer{
          firstName
          lastName
        }
        location{
          id
          name
        }
      }
    }
  }
}

It works and gives me the events for that specific date.

But when I try to fetch for a month, day or year I get the following errors:

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\"}]}']",

I tried using django_filters like so:

# schema.py
...
from django_filters import FilterSet

class EventFilter(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,)

This method doesn't give me the eventDate_Year, eventDate_Month and eventDate_Day augments as the previous method.
How can I achieve this?

keystroke33
  • 159
  • 3
  • 11

0 Answers0