Django Rest Framework-查询映射表中两个字段的完全匹配

时间:2019-05-23 16:17:55

标签: django django-rest-framework

我正在使用DRF,并尝试在映射表中搜索精确匹配项,以便我可以更新该记录。

我有下表:

site
- id
- location
- address

circuit
- id
- name
- ref

sitecircuits
- site_id
- circuit_id
- active_link

我当前的DRF配置如下:

视图

class MonitoringConnectivitySet(viewsets.ModelViewSet):
    queryset = SiteCircuits.objects.all()
    serializer_class = MonitoringSerializerConnectivity
    permission_classes = (IsAdminUser,)   
    filter_class = SiteCircuits
    filter_backends = (filters.SearchFilter,)
    search_fields = ('site__id','circuit__id') 

序列化器

class MonitoringSerializerConnectivity(serializers.ModelSerializer):

    class Meta:
        model = SiteCircuits
        fields = ('site_id','circuit_id','active_link',) 

url

router.register(r'conn_set', views.MonitoringConnectivitySet)

此网址http://localhost:8100/api/conn_set/?site__id=8&circuit__id=7 返回所有结果(因为我根本不搜索)

ive也尝试使用以下内容

URL:

path('conn_set/<int:site_id>/<int:circuit_id>/', views.MonitoringConnectivitySet)

序列化器:

class MonitoringSerializerConnectivity(serializers.ModelSerializer):

    class Meta:
        model = SiteCircuits
        fields = ('site_id','circuit_id','active_link',) 

    def get_queryset(self):
            site_id = self.kwargs['site_id']
            circuit_id = self.kwargs['circuit_id']
            return SiteCircuits.objects.filter(site_id=site_id,circuit_id=circuit_id)        

视图:

class MonitoringConnectivitySet(viewsets.ModelViewSet):
    queryset = SiteCircuits.objects.all()
    serializer_class = MonitoringSerializerConnectivity
    permission_classes = (IsAdminUser,)   

在使用url时也会失败(表明它仅使用一个值而不是两个值) http://localhost:8100/api/conn_set/8/7

有人知道这里合适的组合吗?过滤和更新映射表是否需要做任何特殊的事情?

谢谢

编辑

当重写QuerySet时,出现以下错误:

Traceback:

File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)

File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/usr/local/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view
  54.         return view_func(*args, **kwargs)

File "/usr/local/lib/python3.6/site-packages/rest_framework/viewsets.py" in view
  116.             return self.dispatch(request, *args, **kwargs)

File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
  495.             response = self.handle_exception(exc)

File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py" in handle_exception
  455.             self.raise_uncaught_exception(exc)

File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py" in raise_uncaught_exception
  466.         raise exc

File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
  492.             response = handler(request, *args, **kwargs)

File "/usr/local/lib/python3.6/site-packages/rest_framework/mixins.py" in list
  40.         queryset = self.filter_queryset(self.get_queryset())

File "/usr/local/lib/python3.6/site-packages/rest_framework/generics.py" in filter_queryset
  152.             queryset = backend().filter_queryset(self.request, queryset, self)

File "/usr/local/lib/python3.6/site-packages/django_filters/rest_framework/backends.py" in filter_queryset
  90.         filterset = self.get_filterset(request, queryset, view)

File "/usr/local/lib/python3.6/site-packages/django_filters/rest_framework/backends.py" in get_filterset
  36.         return filterset_class(**kwargs)

File "/usr/local/lib/python3.6/site-packages/django/db/models/base.py" in __init__
  501.                 raise TypeError("%s() got an unexpected keyword argument '%s'" % (cls.__name__, kwarg))

Exception Type: TypeError at /api/conn_set/
Exception Value: SiteCircuits() got an unexpected keyword argument 'data'

3 个答案:

答案 0 :(得分:2)

我认为最简单的解决方案是像这样尝试(覆盖get_queryset方法):

class MonitoringConnectivitySet(viewsets.ModelViewSet):
    queryset = SiteCircuits.objects.all()
    serializer_class = MonitoringSerializerConnectivity
    permission_classes = (IsAdminUser,)   
    filter_class = SiteCircuits

    def get_queryset(self):
        qs = super(MonitoringConnectivitySet, self).get_queryset()
        site = self.request.query_params.get('site')
        circuit = self.request.query_params.get('circuit')
        if site:
            qs = qs.filter(site_id=site)
        if circuit:
            qs = qs.filter(circuit_id=circuit)
        return qs

 # Usage
 http://localhost:8100/api/conn_set/?site=8&circuit=7

答案 1 :(得分:1)

您可以在这里使用django-filter。对于该安装,请按照django-filter installation instructions进行操作,并使用以下代码段。

from django_filters.rest_framework.backends import DjangoFilterBackend


class MonitoringConnectivitySet(viewsets.ModelViewSet):
    queryset = SiteCircuits.objects.all()
    serializer_class = MonitoringSerializerConnectivity
    permission_classes = (IsAdminUser,)
    filter_class = SiteCircuits
    search_fields = ('site__id', 'circuit__id')

    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    filterset_fields = ('site__id', 'circuit__id')

因此,您可以使用URL过滤出结果,

http://localhost:8100/api/conn_set/?site__id=8&circuit__id=7

答案 2 :(得分:0)

我已经在以下方面达到了我想要的结果:

url:

path('conn_set/<int:site_id>/<int:circuit_id>/', views.MonitoringConnectivitySet.as_view())

serialzier:

class MonitoringSerializerConnectivity(serializers.ModelSerializer):

    class Meta:
        model = SiteCircuits
        fields = ('site_id','circuit_id','active_link',) 

视图:

class MonitoringConnectivitySet(generics.GenericAPIView):
    serializer_class = MonitoringSerializerConnectivity
    permission_classes = (IsAdminUser,)   

    def get(self, request, *args, **kwargs):
        site_id = kwargs.get('site_id', '0')
        circuit_id = kwargs.get('circuit_id', '0')
        instance = get_object_or_404(SiteCircuits, site_id=site_id, circuit_id=circuit_id)
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

    def put(self, request, *args, **kwargs):
        site_id = kwargs.get('site_id', '0')
        circuit_id = kwargs.get('circuit_id', '0')
        instance = get_object_or_404(SiteCircuits, site_id=site_id, circuit_id=circuit_id)
        serializer = MonitoringSerializerConnectivity(instance, data=request.data)

        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data,status=status.HTTP_200_OK)
        return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)