如何配置 viewsets.ModelViewSet 以使用请求正文中传递的参数进行过滤。 (Django 休息框架)
How do I configure viewsets.ModelViewSet to filter using arguments passed in the body of the request. (Django Rest Framework )
我正在使用 DJANGO-REST-FRAMEWORK 构建 API。我正在尝试使用传递给请求正文的参数来过滤后端,这是我的设置:
views.py
from .models import UsStatesG
from .serializer import UsStatesSerializer
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.decorators import action
class StatesViewSet(viewsets.ModelViewSet):
queryset = UsStatesG.objects.all()
serializer_class = UsStatesSerializer
@action(detail=False)
def get_by_id(self, request):
body = request.body.decode('utf-8')
body = json.loads(body)
state_list = UsStatesG.objects.filter(st_abbr__in=body['id'])
serializer = self.get_serializer(state_list, many=True)
return Response(serializer.data)
models.py
class UsStatesG(models.Model):
st_fips = models.CharField(primary_key=True, max_length=2, unique=True)
geom = models.MultiPolygonField(blank=False, null=False)
objectid = models.BigIntegerField(blank=False, null=False)
st_name = models.CharField(max_length=50, blank=False, null=False)
st_abbr = models.CharField(max_length=2, blank=False, null=False, unique=True)
class Meta:
managed = False
db_table = 'US_States_G'
urls.py
from django.contrib import admin
from django.urls import include, path, re_path
from api import views
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'states', views.StatesViewSet)
router.register(r'states/q', views.StatesViewSet.get_by_id, basename='UsStatesG')
urlpatterns = [
path('api/location/v1/', include(router.urls)),
serializer.py
from rest_framework_gis.serializers import GeoFeatureModelSerializer
from .models import UsStatesG
class UsStatesSerializer(GeoFeatureModelSerializer):
class Meta:
model = UsStatesG
geo_field = "geom"
fields = ('st_fips', 'st_name', 'st_abbr')
read_only_fields = ('st_fips', 'st_name', 'st_abbr')
我想在请求体中传递参数(隐私问题)
即正文 {"id": ["TX", "CA"]}
我收到此错误:
File "C:\GIT_WS\geospatial\api\REST\APIProject\urls.py", line 31, in <module>
path('api/location/v1/', include(router.urls)),
File "C:\ProgramData\Anaconda3\envs\cgeo\lib\site-packages\rest_framework\routers.py", line 78, in urls
self._urls = self.get_urls()
File "C:\ProgramData\Anaconda3\envs\cgeo\lib\site-packages\rest_framework\routers.py", line 339, in get_urls
urls = super().get_urls()
File "C:\ProgramData\Anaconda3\envs\cgeo\lib\site-packages\rest_framework\routers.py", line 237, in get_urls
routes = self.get_routes(viewset)
File "C:\ProgramData\Anaconda3\envs\cgeo\lib\site-packages\rest_framework\routers.py", line 153, in get_routes
extra_actions = viewset.get_extra_actions()
AttributeError: 'function' object has no attribute 'get_extra_actions'
因为我是使用 DRF 的新手:
1- 这是一个好方法吗?我使用的是正确的视图 类(视图集吗?)?
2- 过滤从请求正文中获取的值的模型的最佳(推荐方法)是什么?
注意:我正在处理地理空间数据,一个 PostgreSQL-PostGIS 后端。我也在使用 rest_framework_gis
示例代码将不胜感激,尤其是 urls.py 和 views.py
的推荐代码
谢谢!
在你的 urls.py 中,你配置了一些错误:
router.register(r'states/q', views.StatesViewSet.get_by_id, basename='UsStatesG')
您想要的视图已包含在行中:
router.register(r'states', views.StatesViewSet)
默认端点是 states/get_by_id/
。如果你想端点是 states/q
,你在 @action
装饰器中配置它。
@action(detail=False, url_path='q')
我正在使用 DJANGO-REST-FRAMEWORK 构建 API。我正在尝试使用传递给请求正文的参数来过滤后端,这是我的设置:
views.py
from .models import UsStatesG
from .serializer import UsStatesSerializer
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.decorators import action
class StatesViewSet(viewsets.ModelViewSet):
queryset = UsStatesG.objects.all()
serializer_class = UsStatesSerializer
@action(detail=False)
def get_by_id(self, request):
body = request.body.decode('utf-8')
body = json.loads(body)
state_list = UsStatesG.objects.filter(st_abbr__in=body['id'])
serializer = self.get_serializer(state_list, many=True)
return Response(serializer.data)
models.py
class UsStatesG(models.Model):
st_fips = models.CharField(primary_key=True, max_length=2, unique=True)
geom = models.MultiPolygonField(blank=False, null=False)
objectid = models.BigIntegerField(blank=False, null=False)
st_name = models.CharField(max_length=50, blank=False, null=False)
st_abbr = models.CharField(max_length=2, blank=False, null=False, unique=True)
class Meta:
managed = False
db_table = 'US_States_G'
urls.py
from django.contrib import admin
from django.urls import include, path, re_path
from api import views
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'states', views.StatesViewSet)
router.register(r'states/q', views.StatesViewSet.get_by_id, basename='UsStatesG')
urlpatterns = [
path('api/location/v1/', include(router.urls)),
serializer.py
from rest_framework_gis.serializers import GeoFeatureModelSerializer
from .models import UsStatesG
class UsStatesSerializer(GeoFeatureModelSerializer):
class Meta:
model = UsStatesG
geo_field = "geom"
fields = ('st_fips', 'st_name', 'st_abbr')
read_only_fields = ('st_fips', 'st_name', 'st_abbr')
我想在请求体中传递参数(隐私问题) 即正文 {"id": ["TX", "CA"]}
我收到此错误:
File "C:\GIT_WS\geospatial\api\REST\APIProject\urls.py", line 31, in <module>
path('api/location/v1/', include(router.urls)),
File "C:\ProgramData\Anaconda3\envs\cgeo\lib\site-packages\rest_framework\routers.py", line 78, in urls
self._urls = self.get_urls()
File "C:\ProgramData\Anaconda3\envs\cgeo\lib\site-packages\rest_framework\routers.py", line 339, in get_urls
urls = super().get_urls()
File "C:\ProgramData\Anaconda3\envs\cgeo\lib\site-packages\rest_framework\routers.py", line 237, in get_urls
routes = self.get_routes(viewset)
File "C:\ProgramData\Anaconda3\envs\cgeo\lib\site-packages\rest_framework\routers.py", line 153, in get_routes
extra_actions = viewset.get_extra_actions()
AttributeError: 'function' object has no attribute 'get_extra_actions'
因为我是使用 DRF 的新手:
1- 这是一个好方法吗?我使用的是正确的视图 类(视图集吗?)?
2- 过滤从请求正文中获取的值的模型的最佳(推荐方法)是什么?
注意:我正在处理地理空间数据,一个 PostgreSQL-PostGIS 后端。我也在使用 rest_framework_gis
示例代码将不胜感激,尤其是 urls.py 和 views.py
的推荐代码谢谢!
在你的 urls.py 中,你配置了一些错误:
router.register(r'states/q', views.StatesViewSet.get_by_id, basename='UsStatesG')
您想要的视图已包含在行中:
router.register(r'states', views.StatesViewSet)
默认端点是 states/get_by_id/
。如果你想端点是 states/q
,你在 @action
装饰器中配置它。
@action(detail=False, url_path='q')