Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django REST框架自定义更新方法_Python_Django_Django Rest Framework - Fatal编程技术网

Python Django REST框架自定义更新方法

Python Django REST框架自定义更新方法,python,django,django-rest-framework,Python,Django,Django Rest Framework,我的应用程序具有以下结构: models.py views.py 目前,为了更新EventHost表,我正在进行http put,在我的url中提供id(这是主键) 我希望能够更新提供主机名和事件名(将在url中传递)而不是id的EventHost 使用SQL时,它将如下所示: update eventhost set someparam='somevalue' from eventhost as a, event as b, host as c where b.id = a.eventid a

我的应用程序具有以下结构:

models.py

views.py

目前,为了更新EventHost表,我正在进行http put,在我的url中提供id(这是主键)

我希望能够更新提供主机名和事件名(将在url中传递)而不是id的EventHost

使用SQL时,它将如下所示:

update eventhost set someparam='somevalue' from eventhost as a, event as b, host as c where b.id = a.eventid and c.hostid = a.hostid and b.eventname='myevent' and c.hostname='myhost';

从文档中我了解到,我需要修改viewset的默认更新方法或/和修改queryset。您知道如何实现吗?

您可以覆盖
get\u object
方法,并使用url提供的参数,如下所示:

class EventHostViewSet(viewsets.ModelViewSet):
    queryset = EventHost.objects.all()
    serializer_class = EventHostSerializer

    def get_object(self):
       return EventHost.objects.get(hostid=self.kwargs['hostid'],eventid=self.kwargs['eventid'])

通过这种方式,您必须管理此查询场景中是否没有记录,假设您已经正确构造了URL,则可以自定义

编辑的EventHostViewSet.get_对象方法:

class EventHostViewSet(viewsets.ModelViewSet):
    ...
    lookup_field = 'eventname'
    def get_object(self):
        queryset = self.filter_queryset(self.get_queryset())

        filter_kwargs = {'hostid__hostname': self.kwargs.get('hostname'),
                         'eventid__eventname': self.kwargs.get('eventname')}
        obj = get_object_or_404(queryset, **filter_kwargs)

        self.check_object_permissions(self.request, obj)
        return obj
EventHostViewSet注册:

router.register(rf'event-hosts/(?p[.]+'),EventViewSet)

关于您的问题的一些评论:

  • 当您的系统中存在两个具有相同hostid\uuu主机名和eventid\uuu事件的EventHost时,您会遇到问题,因为queryset get方法应该只返回一条记录
  • 在DRF中,PUT方法需要在请求数据中提供所有字段,若要更新选定字段,应使用PATCH方法或override update viewset方法(将partial设置为True)
再次编辑


这是一个非常糟糕的设计,您不应该这样做(不知何故,您应该使用id/maybe@action decorator来构建特定的url,以便像这样进行更新)。

谢谢。我应该如何在url.py中构造它?目前看起来是这样的:
router=routers.DefaultRouter()router.register(r'accounts',AccountViewSet)router.register(r'events',EventViewSet)router.register(r'hosts',HostViewSet)urlpatterns=[url(r“^api/v1/”,include(router.url)),]
我可以在route.register中使用一些正则表达式吗?我再次编辑了答案。这是一个非常糟糕的设计(但它解决了您的问题-解决方法)您应该使用不同的解决方案。您能给我一个应该在这里使用的url示例吗?我仍在努力使其工作…/event hosts/SOMEHOSTNAME/SOMEEVENTNAME
class EventHostViewSet(viewsets.ModelViewSet):
    queryset = EventHost.objects.all()
    serializer_class = EventHostSerializer

    def get_object(self):
       return EventHost.objects.get(hostid=self.kwargs['hostid'],eventid=self.kwargs['eventid'])
class EventHostViewSet(viewsets.ModelViewSet):
    ...
    lookup_field = 'eventname'
    def get_object(self):
        queryset = self.filter_queryset(self.get_queryset())

        filter_kwargs = {'hostid__hostname': self.kwargs.get('hostname'),
                         'eventid__eventname': self.kwargs.get('eventname')}
        obj = get_object_or_404(queryset, **filter_kwargs)

        self.check_object_permissions(self.request, obj)
        return obj