Django/Wagtail Rest API URL Filter без ответа
Я использую Wagtail и у меня есть API под названием 127.0.0.1:8000/api/v2/stories
. В API я имею следующий ответ JSON
{
"count": 81,
"results": [
{
"id": 122,
"title": "Test Blog",
"blog_authors": [
{
"id": 82,
"meta": {
"type": "blog.BlogAuthorsOrderable"
},
"author_name": "Test",
"author_website": null,
"author_status": false,
},
{
"id": 121,
"title": "Test Blog 1",
"blog_authors": [
{
"id": 81,
"meta": {
"type": "blog.BlogAuthorsOrderable"
},
"author_name": "Test",
"author_website": null,
"author_status": false,
},
}
Основная проблема, с которой я сталкиваюсь, заключается в том, что я хочу отфильтровать по имени автора. Я выполнил этот запрос в URL ?author_name=Test
& ?blog_authors__author_name=Test
& ?author__name=Test
Но ответ был
{
"message": "query parameter is not an operation or a recognised field: author_name"
}
Я добавил эти поля в known_query_parameters
, но ответ был таким же, как api/v2/stories/
. Я пробовал DjangoFilterBackend, но каждый раз получал один и тот же ответ. Как я могу фильтровать по author_name
& author_status
в API?
Вот мой api.py
class ProdPagesAPIViewSet(BaseAPIViewSet):
renderer_classes = [JSONRenderer]
pagination_class = CustomPagination
filter_backends = [FieldsFilter,
ChildOfFilter,
AncestorOfFilter,
DescendantOfFilter,
OrderingFilter,
TranslationOfFilter,
LocaleFilter,
SearchFilter,]
known_query_parameters = frozenset(
[
"limit",
"offset",
"fields",
"order",
"search",
"search_operator",
# Used by jQuery for cache-busting. See #1671
"_",
# Required by BrowsableAPIRenderer
"format",
"page","author_name",
]
)
meta_fields = ["type","seo_title","search_description","first_published_at"]
body_fields = ["id","type","seo_title","search_description","first_published_at","title"]
listing_default_fields = ["type","seo_title","search_description","first_published_at","id","title","alternative_title","news_slug","blog_image","video_thumbnail","categories","blog_authors","excerpt","content","content2","tags","story_type"]
nested_default_fields = []
def get_queryset(self):
return super().get_queryset().filter(story_type='Story').order_by('-first_published_at')
name = "stories"
model = AddStory
api_router.register_endpoint("stories", ProdPagesAPIViewSet)
О взглядах трясогузки можно узнать здесь
вот мой models.py
для авторов блогов.
class BlogAuthorsOrderable(Orderable):
"""This allows us to select one or more blog authors from Snippets."""
page = ParentalKey("blog.AddStory", related_name="blog_authors")
author = models.ForeignKey(
"blog.BlogAuthor",
on_delete=models.CASCADE,
)
panels = [
# Use a SnippetChooserPanel because blog.BlogAuthor is registered as a snippet
FieldPanel("author"),
]
@property
def author_name(self):
return self.author.name
@property
def author_website(self):
return self.author.website
@property
def author_image(self):
return self.author.image
@property
def author_status(self):
return self.author.status
api_fields = [
APIField("author_name"),
APIField("author_website"),
APIField("author_status"),
# This is using a custom django rest framework serializer
APIField("author_image", serializer=ImageSerializedField()),
# The below APIField is using a Wagtail-built DRF Serializer that supports
# custom image rendition sizes
APIField(
"image",
serializer=ImageRenditionField("fill-200x250|format-webp",
source="author_image"
)
),
]
@register_snippet
class BlogAuthor(models.Model):
"""Blog author for snippets."""
name = models.CharField(max_length=100)
status = models.BooleanField(default=False, verbose_name="Special Author")
website = models.URLField(blank=True, null=True)
image = models.ForeignKey(
"wagtailimages.Image",
on_delete=models.SET_NULL,
null=True,
blank=False,
related_name="+",
)
panels = [
MultiFieldPanel(
[
FieldPanel("name"),
# Use an ImageChooserPanel because wagtailimages.Image (image property)
# is a ForeignKey to an Image
FieldPanel("image"),
FieldPanel("status"),
],
heading="Name, Image and Status",
),
MultiFieldPanel(
[
FieldPanel("website"),
],
heading="Links"
)
]
def __str__(self):
"""String repr of this class."""
return self.name
class Meta: # noqa
verbose_name = "Blog Author"
verbose_name_plural = "Blog Authors"
Вот как я называл авторов блогов
class AddStory(Page):
"""Blog detail page."""
content_panels = Page.content_panels + [
MultiFieldPanel(
[
InlinePanel("blog_authors", label="Author", min_num=1, max_num=4)
],
heading="Author(s)"
),
]
api_fields = [
APIField("blog_authors"),
]
Вам необходимо добавить пользовательский фильтр для обработки параметра author_name. Как и фильтры, предоставляемые самим Wagtail, он, вероятно, должен наследоваться от from rest_framework.filters import BaseFilterBackend