Как фильтровать изображения по коллекции в Wagtail API v2
У меня есть тип Page с внешним ключом к Collections:
class PageWithManyPhotos(Page):
collection = models.ForeignKey("wagtailcore.Collection", ...)
Я хочу получить все изображения из коллекции, выбранной для страницы, через API. В идеале - из конечной точки pages, но можно и из конечной точки images (для этого потребуется дополнительный запрос, сначала для получения идентификатора коллекции, а затем для фильтрации изображений по коллекции)
1-й подход
Когда я добавляю APIField в модель Page: api_fields = [APIField("collection", serializer=CollectionSerializer())]
class CollectionSerializer(ModelSerializer):
images = ImageSerializer(read_only=True, many=True)
class Meta:
model = Collection
# fields = ["id", "name", "images"]
exclude = []
и сделать запрос по адресу /api/v2/pages/?type=base.GalleryPage&fields=collection
, я получаю ответ, но без изображений:
"collection": {
"id": 8,
"path": "000100050003",
"depth": 3,
"numchild": 0,
"name": "Collection 1"
}
Я не могу получить обратную зависимость. Возможно, потому что Collection - это MP_Node, а не models.Model?
2-й подход
Я также попробовал второй подход - добавить пользовательский набор представлений в конечной точке /api/v2/images/?collection=<collection_id>
и фильтровать изображения по коллекции в конечной точке images. Поле коллекции отсутствует в default fields. Я попытался добавить его, сделав что-то вроде:
class CollectionField(Field):
def get_attribute(self, instance):
return instance
def to_representation(self, image):
return image.collection_id
class CustomImageSerializer(BaseSerializer):
collection = CollectionField(read_only=True)
class CustomImagesAPIViewSet(ImagesAPIViewSet):
meta_fields = BaseAPIViewSet.meta_fields + ["collection"]
base_serializer_class = CustomImageSerializer
api_router.register_endpoint("images", CustomImagesAPIViewSet)
Из вашего сообщения мне не ясно, дает ли ваш второй подход желаемый результат.
Ваш первый подход не работает, потому что отношения между коллекциями и изображениями определяются с помощью related_name="+"
, что означает, что вы можете сказать my_collection.images.all()
. Я думаю, вы все же сможете это сделать, если определите поле images с помощью SerializerMethodField и затем попросите вашу функцию get_images
вернуть все изображения с collection_id = <id коллекции страницы>