有下一个Django REST问题。
我有看法。
class MessageViewSet(viewsets.ModelViewSet):
serializer_class = MessageSerializer
queryset = Message.objects.filter(isread = False)
def mark_read():
queryset = Message.objects.update(isread=True)
return Response({'read':queryset})
和urls.py中的路由器
router = SimpleRouter() router.register(r'api/get_messages', MessageViewSet)
urlpatterns = [
url(r'^$', MainView.as_view(), name='main'),
url(r'^', include(router.urls)) ]
现在我有'get_messages'页面显示所有列表。
当我访问'mark_read'页面时,如何实现一个方法,将模型实例的'isread'值从False更改为True? 如您所见,我试图在课堂上编写方法。但是,当我试图用这种方式在网址中调用它时:
router.register(r'api/mark_read', MessageViewSet.mark_read),
出现错误。
断言queryset不是None,'
base_name
参数未指定,并且可能'\' AssertionError:base_name
参数未指定,并且无法自动确定视图集中的名称,因为它没有.queryset
属性。
也许我不应该使用路由器,并以其他方式重写视图和网址。如果你知道如何解决这个问题,请回答。谢谢。
答案 0 :(得分:2)
您可以使用detail_route
或list_route
装饰器。
from rest_framework.decorators import list_route
class MessageViewSet(viewsets.ModelViewSet):
@list_route()
def mark_read(self, request):
queryset = Message.objects.update(isread=True)
return Response({'read':queryset})
mark_read
可以使用api/get_messages/mark_read
方法。而且您不需要创建单独的路由器,只需使用您为MessageViewSet
答案 1 :(得分:2)
由于您使用的是模型视图集,因此您可以直接使用put或patch rest方法将所需字段作为数据发送到所需字段。 理想情况下,休息时不应更改模型值。如果你真的想要一个不同的终点,那就把list_route或detail_route装饰器放在你的mark_read方法上,并使它们成为一个只有put和/或patch调用的有效调用
from rest_framework.decorators import list_route
class MessageViewSet(viewsets.ModelViewSet):
@list_route(methods=['Patch', 'PUT'])
def mark_read(self, request):
queryset = Message.objects.update(isread=True)
return Response({'read':queryset})
答案 2 :(得分:0)
感谢@ ivan-semochkin和@Shaumux的回复。建议真有帮助。
这是我的路线。我使用了detail_route而不是list_route。
@detail_route(methods=['get','put'], url_name='mark_read/')
def mark_read(self, request, pk=None):
queryset = Message.objects.filter(pk=pk).update(isread=True)
return Response({'read':queryset})
现在,'isread'值正在改变,我访问'mark_read'页面。 链接:“api / get_messages / pk / mark_read”
有谁知道,是否可以通过下一个方式建立链接: “api / get_messages” - 列表,“api / mark_read / pk” - 更改读取值。
是否可以创建这样的东西? “API / mark_read?= PK”