React.js前端的Django REST框架后端过滤问题

问题描述 投票:0回答:1

因此,我尝试使用一些多余的实践和技术来展示一个不太简单的Todo应用程序,以展示开发技能。该应用程序应为Trello副本。后端是Django,它利用django REST框架处理来自前端(即React.js)的RESTful api请求。简而言之,我在使用django_backend时遇到了麻烦,尤其是django-rest-framework时遇到了麻烦,似乎不希望被要求过滤其查询集。我已经尝试了几个django软件包以及DRF文档中描述的方法,我将对其进行详细说明,但是我的尝试没有用,我希望获得一些指导。谢谢!

后端设置

我刚刚完成了redux-saga的实现,并且我有一些非常基本的概述,可以获取每个模型的每个实例。但是我显然不想请求每个实例,因此我们应该过滤响应。

Django REST框架使用诸如Serializers和ViewSets之类的内置类返回模型实例的列表,其余框架可以使用它们响应请求。这些是我用于测试对后端的请求的初始视图集,它们都将适当的JSON对象返回给我的前端:viewsets.py

from rest_framework import viewsets
from corkboard.models import Card, Stage, Board
from .serializers import CardSerializer, StageSerializer, BoardSerializer
# Card is the model for a "Todo" Instance
# Todo Cards viewset
class CardViewSet(viewsets.ModelViewSet):
    queryset = Card.objects.all()
    serializer_class = CardSerializer

# Stages of completion model viewsets
class StageViewSet(viewsets.ModelViewSet):
    queryset = Stage.objects.all()
    serializer_class = StageSerializer

# Board that "houses" all stages and cards
class BoardViewSet(viewsets.ModelViewSet):
    queryset = Board.objects.all()
    serializer_class = BoardSerializer

viewseturls.py:

from rest_framework import routers
from .views import CardViewSet, StageViewSet, BoardViewSet


# registering router paths for each of the viewsets
router = routers.DefaultRouter()
router.register('cards', CardViewSet, 'cards')
router.register('stages', StageViewSet, 'stages')
router.register('boards', BoardViewSet, 'boards')

urlpatterns = router.urls

并且这些url用于通过axios从前端进行的调用。最初,我尝试仅通过类似

的方法更改请求中的URL。

axios.get(`http://localhost:8000/api/cards)

to

axios.get(`http://localhost:800/api/cards/?stage=1`)

此不同的URL响应相同的JSON对象(所有卡实例,无论阶段如何)

查看DRF filtering docs显示了一些有用的过滤方法。它们涉及创建另一个视图类来覆盖get_queryset方法,如下所示:

from rest-framework import generics

class CardsFilteredByStageViewSet(generics.ListAPIView):
    serializer_class = TodoSerializer

    def get_queryset(self):
        """
        This view should return a list of all the todo cards for
        the stage as determined by the stage portion of the URL.
        """
        stage = self.kwargs['stage']
        return Card.objects.filter(stage=stage)

注意,这涉及使用

rest-framework.generics.ListAPIView

而且我也尝试从]继承>

views.ViewSets

两者之后,我去编辑urls.py中的路由器URL:

from .views import StageCardViewSet

router.register('stage_cards', StageCardViewSet, 'stage_cards') 

然后尝试

http://localhost:8000/api/stage_cards/

http://localhost:8000/api/stage_cards/?stage=1

但是两个都出现了KeyError:

Request Method: GET
Request URL:    http://localhost:8000/api/stage_cards/?stage=1
Django Version: 3.0.5
Exception Type: KeyError
Exception Value: 'stage'

DRF文档还提供了django-filter之类的软件包的源,并且安装似乎正常。我用过

pipenv install django-filter

正如您稍后将在本文中看到的那样,此软件包同时出现在我的requirements.txt和我的Pipfile中,因此肯定已安装。它也已添加到django_backend.settings中。 Yes, the 's' is supposed to be in 'django-filters' below

 INSTALLED_APPS = [
    # confusing pluralization
    'django-filters',
    ...
]

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
    ],
    ...
} 

如果未将其添加为软件包,这会给出错误,对吗?

在将其添加为已安装的应用程序之后,开发现有的视图集(或通用列表,取决于您使用的是什么)

from django_filters.rest_framework import DjangoFilterBackend #added

class CardViewSet(viewsets.ModelViewSet):
    queryset = Card.objects.all()
    serializer_class = CardSerializer
    filter_backends = [DjangoFilterBackend] #added
    filterset_fields = ['stage', 'id']      #added

但是我在IDE中收到“无法导入”错误。探索此错误后,发现this article建议添加django-rest-framework-filters

,但是在安装后,我立即开始收到有关没有[[django.utils.six的错误,我发现了has been removed from django > 3 ],但是django-rest-framework-filters是必需的。尽管其他一些文档提到很多d-r-r-f功能被添加回django-filter中。删除/卸载d-r-f-f可以修复错误并允许服务器运行,但是我仍然收到关于无法将django-filter导入到我的视图集的红色底线:Unable to import 'django_filters.rest_framework'pylint(import-error)
在更新的视图中:

from django_filters.rest_framework import DjangoFilterBackend #^^^ here is the unable to import error underline

我只想过滤模型的实例,以便将相关信息返回给前端。请帮助。

额外,可能是相关信息

尽管我的项目还包含用于本地VDE的Pip文件,但它也具有用于安装Docker构建依赖项的requirements.txt文件。我都包括在内。requirements.txt:

appdirs==1.4.3 asgiref==3.2.7 astroid==2.3.3 certifi==2019.11.28 distlib==0.3.0 Django==3.0.5 django-environ==0.4.5 django-filter==2.2.0 djangorestframework==3.11.0 filelock==3.0.12 isort==4.3.21 lazy-object-proxy==1.4.3 mccabe==0.6.1 pipenv==2018.11.26 pylint==2.4.4 pylint-django==2.0.15 pylint-plugin-utils==0.6 pytz==2019.3 six==1.14.0 sqlparse==0.3.1 virtualenv==20.0.2 virtualenv-clone==0.5.3 wrapt==1.11.2

Pipfile:

[[source]] name = "pypi" url = "https://pypi.org/simple" verify_ssl = true [dev-packages] [packages] appdirs = "==1.4.3" asgiref = "==3.2.7" astroid = "==2.3.3" certifi = "==2019.11.28" distlib = "==0.3.0" djangorestframework = "==3.11.0" filelock = "==3.0.12" isort = "==4.3.21" lazy-object-proxy = "==1.4.3" mccabe = "==0.6.1" pipenv = "==2018.11.26" pylint = "==2.4.4" pytz = "==2019.3" six = "==1.14.0" sqlparse = "==0.3.1" virtualenv = "==20.0.2" virtualenv-clone = "==0.5.3" wrapt = "==1.11.2" Django = "==3.0.5" django-environ = "*" django-filter = "*" [requires] python_version = "3.8"

django_backend的Dockerfile:

# Use an official Python runtime as a parent image FROM python:latest # Adding backend directory to make absolute filepaths consistent across services WORKDIR /usr/src/app/django-backend # Install Python dependencies ADD requirements.txt . RUN pip3 install --upgrade pip -r requirements.txt # Add the rest of the code ADD . . # Make port 8000 available for the app EXPOSE 8000 # Be sure to use 0.0.0.0 for the host within the Docker container, # otherwise the browser won't be able to find it CMD python3 manage.py runserver 0.0.0.0:8000

前端

前端是

React.js和reduxredux-saga。我认为这与这篇文章无关,因为一切都运行良好,直到我开始在django_backend中更改代码

当然,如果我不够清楚,请问任何问题,并先谢谢。

因此,我尝试使用一些多余的实践和技术来展示一个不太简单的Todo应用程序,以展示开发技能。该应用程序应该是一种...

django django-rest-framework docker-compose django-filter pipenv
1个回答
0
投票
我的第一篇文章最终是因为一个愚蠢的错误。我自己回答,因为为什么不呢。
© www.soinside.com 2019 - 2024. All rights reserved.