【问题标题】:API Query in Django Rest FrameworkDjango Rest Framework 中的 API 查询
【发布时间】:2022-11-13 06:51:15
【问题描述】:

我从数据库创建了一个 API,我可以查看 API,但我无法通过 URL 进行查询,例如:127.0.0.1:8000/author?author_id=9,我不确定在哪里添加查询代码。我想使用字段进行过滤。这是我的models.py

class AuthorAPI(models.Model):
    author_id=models.IntegerField()
    name=models.TextField()
    author_img_url=models.TextField()
    title=models.TextField()
    first_published_at=models.DateTimeField()
    excerpt=models.TextField()

    class Meta:
        db_table = 'view_author'

serializers.py

from rest_framework import serializers
from .models import SortAPI, AuthorAPI
class AuthorAPISerializer(serializers.ModelSerializer):
    class Meta:
        model=AuthorAPI
        fields='__all__'

views.py

from .serializers import APISerializer,AuthorAPISerializer
from .models import SortAPI, AuthorAPI
from rest_framework.response import Response
from rest_framework.decorators import api_view
@api_view(['GET'])
def getauthor(request):
    if request.method == 'GET':
        results = AuthorAPI.objects.all()
        serialize = AuthorAPISerializer(results, many=True)
        return Response(serialize.data)

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    在您看来,请使用ModelViewset

    并添加 fliter_backend 属性:

    filter_backends = [django_filters.rest_framework.DjangoFilterBackend]
    

    在文档中查看此处:

    https://www.django-rest-framework.org/api-guide/filtering/#setting-filter-backends

    class AuthorViewset(viewsets.ReadOnlyModelViewset):
        serializer_class = AuthorAPISerializer
        queryset = AuthorAPI.objects.all()
        filter_backends = [django_filters.rest_framework.DjangoFilterBackend]
    

    重要的

    使用django_filter 将需要您安装额外的要求,但它非常值得,请参阅此处django_filter 的安装步骤:

    https://django-filter.readthedocs.io/en/stable/guide/install.html

    在您的urls.py 中,您需要使用SimpleRouter 注册您的查看器,如此处文档中所述:

    https://www.django-rest-framework.org/api-guide/viewsets/#example

    此外,您需要设置filterset_fields 来告诉DRF 您希望允许用户过滤哪些字段。

    如此处的文档中所述:

    https://django-filter.readthedocs.io/en/stable/guide/rest_framework.html#using-the-filterset-fields-shortcut

    在文档中可能没有足够强调的重要警告词是这一点:

    请注意,不支持同时使用 filterset_fields 和 filterset_class。

    完成后,如果您浏览至/author,您应该会看到一些可用的过滤器控件,等等

    【讨论】:

      【解决方案2】:

      您可以使用 request.GET 从 URL 参数中获取数据。

      试试这个

      @api_view(['GET'])
      def getauthor(request):
          if request.method == 'GET':
      
              results = AuthorAPI.objects.all()
      
              # get author_id from the url query parameter
              author_id = request.GET.get('author_id', None)
              
              #if author_id is present in the url query parameter then filter the resluts queryset based on the author_id
              if author_id:
                  results = results.filter(author_id=author_id)
      
              serialize = AuthorAPISerializer(results, many=True)
              return Response(serialize.data)
      

      【讨论】:

      • 谢谢,工作。如果我想过滤多个字段怎么办?例如,身份证、姓名、状态、头衔?我应该为每个字段单独添加它吗?
      • 如果要在当前方案中过滤许多字段,则必须单独添加。更好的是,您可以切换到基于类的视图和用户 Django REST 框架的过滤器,以过滤多个字段,如@Swift 的上一个答案中所述。
      【解决方案3】:

      感谢 Swift,但出现了一些错误,viewsets.ReadOnlyModelViewset 无法正常工作,所以我尝试了这个

      views.py

      import django_filters.rest_framework
      from django.contrib.auth.models import User
      from rest_framework import generics,viewsets,filters
      from django_filters.rest_framework import DjangoFilterBackend,OrderingFilter
      from rest_framework.pagination import PageNumberPagination
      from rest_framework.renderers import JSONRenderer
      
      class CustomPagination(PageNumberPagination):
          page_size = 50
          page_size_query_param = 'page_size'
          max_page_size = 1000
      
      class AuthorViewset(generics.ListAPIView):
          renderer_classes = [JSONRenderer]
          pagination_class = CustomPagination
          serializer_class = AuthorAPISerializer
          queryset = AuthorAPI.objects.all()
          filter_backends = [DjangoFilterBackend,filters.SearchFilter,filters.OrderingFilter]
          filterset_fields = ['name', 'id','author_id','status','title','first_published_at','story_type']
          search_fields=['id','author_id','name','title','first_published_at']
          ordering_fields=['id','author_id','name','title','first_published_at']
      
          class Meta:
              name="AuthorViewset"
      

      我本可以使用 Sumithran 的答案,但如果我想允许多个字段,这有点复杂,因为对于每个字段,我必须添加相同的代码并进行一些修改,这可能会增加代码行。

      【讨论】:

      • 您可以接受自己的答案 :) 但我们也可以在 cmets 中进行讨论,我会对其进行更新以更好地适应您的用例。我们答案的不同之处在于,使用ReadOnlyModelViewset,您还可以获得单个作者对象,并且还可以返回更详细的信息。
      • 哦对不起。我昨天试图编辑你的答案,但被拒绝了。我完全忘记了评论。
      • 我不能审查编辑,即使是在我自己的帖子上,我还没有这个特权。
      • 它可能被拒绝了,因为如果您在收到我们部分正确的答案的过程中发现它,实际上鼓励回答您自己的问题。这并不意味着我的或其他答案不会被阅读,因为它不被接受
      猜你喜欢
      • 2020-10-28
      • 2018-10-26
      • 2020-09-25
      • 2020-06-24
      • 2023-03-30
      • 2018-10-14
      • 1970-01-01
      • 2018-06-17
      • 2018-10-23
      相关资源
      最近更新 更多