【问题标题】:Simple Filter in django rest frameworkdjango rest框架中的简单过滤器
【发布时间】:2017-02-16 23:43:58
【问题描述】:

我有 2 个模型:作者和评论。我需要获取按 author_id 过滤的 cmets 列表!像这样的:

  1. api/authors/author_id/cmets
  2. 或者这个:api/cmets?author_id=author_id
  3. 或者这个:api/cmets/author/author_id

这里是官方文档:http://www.django-rest-framework.org/api-guide/filtering

这里有类似的问题:Filtering in django rest framework

这对我没有帮助。不幸的是,互联网上没有这个任务的完整简单示例。

请告诉我,我应该在我的代码中更改什么来执行此过滤?

我的代码:

# models.py
from django.db import models
from django.utils import timezone

class Author(models.Model):
    name = models.CharField(max_length=200)

class Comment(models.Model):
    author = models.ForeignKey('Employee', related_name='author_comments')
    text = models.TextField(blank=True)
    published = models.BooleanField(default=True)
# serializer.py
from rest_framework import serializers
from core.models import Author, Comment

class AuthorSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Author
        fields = '__all__'

class CommentSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Comment
        fields = '__all__'
# views.py
from rest_framework import viewsets
from models import  Author, Comment
from serializers import AuthorSerializer, CommentSerializer

class CommentViewSet(viewsets.ModelViewSet):
    queryset = Club.objects.all()
    serializer_class = ClubSerializer
# urls.py
from django.conf.urls import url, include
from rest_framework import routers
from . import views

router = routers.DefaultRouter()
router.register(r'comments', views.CommentViewSet)

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    DRF-extensions 有一个名为 Nested routes 的功能,允许您将路由逻辑附加到 ViewSets(这是您的情况)。它看起来像你想要的,也是最简单的。

    【讨论】:

    • 在您的答案中包含引文很好,但是如果您包含示例中您认为最有助于回答问题的部分,它会大大改善它。这样,如果将来链接断开,相关信息仍然存在。
    【解决方案2】:

    您需要创建过滤查询集。在此示例中,我按作者 ID 过滤了 cmets

    views.py

    class CommentFilter(generics.ListAPIView):
        serializer_class = CommentSerializer
    
        def get_queryset(self):
            """
            This view should return a list of all the comments for
            particular author by author portion of the URL.
            """
            username = self.kwargs['author_id']
            return Comment.objects.filter(author__id=author_id)
    

    urls.py

    from django.conf.urls import url, include
    from rest_framework import routers
    from . import views
    
    router = routers.DefaultRouter()
    router.register(r'comments', views.CommentViewSet)
    router.register(r'comment_list/(?P<author_id>\d+)/?$', views.CommentFilter,base_name="comment_list")
    

    希望它有效。

    【讨论】:

    • 我应该在哪里添加这个代码(我应该使用什么文件)?我应该更改 urls.py 或其他文件中的某些内容吗?如果我将这个类添加到视图中,并在 urls.py 中使用它——我得到一个错误:AssertionError: base_name 参数未指定,并且无法从视图集中自动确定名称,因为它没有.queryset 属性。
    • 我收到一个错误:AssertionError: base_name 参数未指定,并且无法从视图集中自动确定名称,因为它没有 .queryset 属性
    • router.register(r'comment_list/(?P\d+)/?$', views.CommentFilter base_name="comment_list")
    • 另一个错误:view = viewset.as_view(mapping, **route.initkwargs) TypeError: as_view() 需要 1 个位置参数,但给出了 2 个
    • 试试views.CommentFilter.as_view()
    【解决方案3】:

    嵌套 URL 在 DRF 中是不必要的困难。作为您链接提示的问题,最简单的方法是提取一个查询参数:

    class CommentViewSet(viewsets.ModelViewSet):
        serializer_class = ClubSerializer
    
        def get_queryset(self):
            queryset = Club.objects.all()
            author_id = self.request.query_params.get('author_id')
    
            if author_id is not None:
                queryset = queryset.filter(author_id=author_id)
            return queryset
    

    您可以像上面的选项 2 一样使用它:

    api/comments?author_id=author_id

    【讨论】:

    • 这可行,但您需要使用 generics.ListAPIView 而不是视图集。
    猜你喜欢
    • 2014-02-17
    • 2012-12-24
    • 2017-05-27
    • 1970-01-01
    • 2017-10-26
    • 2018-05-17
    • 2019-03-06
    • 1970-01-01
    • 2018-04-21
    相关资源
    最近更新 更多