Как выполнить фильтр django по связанному полю со связанным именем в graphene

У меня есть модель событий с внешними ключами к моделям местоположения и фотографа.

# event model
...
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="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=50, choices=STATUS, default="Scheduled")
    created = models.DateTimeField(auto_now_add=True)

Модель фотографа имеет first_name, last_name и email в качестве свойств. Я хотел бы иметь возможность фильтровать события, указывая данные фотографа, например, его email. В своем REST api я сделал так, что я могу передать любой запрос фильтра django в url следующим образом: /events/?photogrpher__email=name@example.com. Я пытаюсь воспроизвести такое же поведение в graphql с помощью graphene.

# types.py
...
class EventType(DjangoObjectType):
    class Meta:
        model = Event
        interfaces = (relay.Node,)
        filterset_class = EventFilter


class LocationType(DjangoObjectType):
    class Meta:
        model = Location
        filterset_class = LocationFilter
        interfaces = (relay.Node,)

class PhotographerType(DjangoObjectType):
    class Meta:
        model = Photographer
        filterset_class = PhotographerFilter
        interfaces = (relay.Node,)

Фильтры:

# filters.py
...
class PhotographerFilter(FilterSet):
    class Meta:
        model = Photographer
        fields = "__all__"

        exclude = [
            "password",
            "profile_picture",
        ]


class EventFilter(FilterSet):

    class Meta:
        model = Event
        fields = "__all__"
        filter_fields = {
            "event_photographer": ["exact", "first_name", "last_name", "email"],
            "event_location": ["exact", "name"],
        }

class LocationFilter(FilterSet):
    class Meta:
        model = Location
        fields = "__all__"

Запрос:

# queries.py
...
class Query(ObjectType):
    all_photographers = DjangoFilterConnectionField(PhotographerType)
    photogrpaher = relay.Node.Field(PhotographerType)
    event = relay.Node.Field(EventType)
    all_events = DjangoFilterConnectionField(EventType)
    location = relay.Node.Field(LocationType)
    all_location = AdvancedDjangoFilterConnectionField(LocationType)

В результирующем api нет связанных полей в качестве аргументов, только поля модели. Я попробовал добавить поле event_photographer вручную:

# filters.py
...
class EventFilter(FilterSet):
    event_photographer = django_filters.CharFilter(field_name="event_photographer")
...

При таком добавлении, когда я передаю любую строку, я получаю параметр eventPhotographer, но не подпараметры, такие как firstName, email и т.д. Пример запроса выглядит так:

    allEvents(eventPhotographer:"name@example.com"){
        edges {
            node {
                id
                photographer {
                    firstName
                }
           }
        }
    }

Выдает эту ошибку:

"message": "Cannot resolve keyword 'event_photographer' into field. Choices are: blocked_slot_event, booked_day_event, booked_slot_event, calendar_event, created, event_date, event_shoot, id, location, location_id, photographer, photographer_id, product_sale_event, set_photos, status",

Дополнительные поля являются связанными именами для других моделей, которые имеют внешний ключ к Events

Что я делаю неправильно и какой правильный и самый простой способ достичь этого.

Вы определенно можете сделать что-то подобное (см. двойное подчеркивание между моделью и колонкой):

# filters.py
class PhotographerFilter(FilterSet):
    class Meta:
        model = Photographer
        fields = "__all__"


class EventFilter(FilterSet):
    photographer__name = CharFilter()
    
    class Meta:
        model = Event
        fields = "__all__"

Этот запрос будет работать и фильтровать по имени фотографа:

query {
    allEvents(photographer_Name: "maro") {
        edges {
            node {
                photographer {
                    name
                }
            }
        }
    }
}

Вы можете добавить соответствующие фильтры для firstName, email и т.д.

Вернуться на верх