Как выполнить фильтр 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 и т.д.