Django Rest_Framework:在模板中调用删除方法



我正在尝试将示例应用程序从 Rest 框架教程转换为带有模板的应用程序。问题是我无法在单个记录的详细信息视图中创建删除按钮。 我 views.py 如下:

class SnippetViewSet(viewsets.ModelViewSet):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly,)
renderer_classes = [renderers.TemplateHTMLRenderer]
template_name = 'list.html'

def list(self, request, **kwargs):
print(request.method, request.user)
queryset = Snippet.objects.all()
serializer = SnippetSerializer(context={'request': request})
return Response({'queryset': queryset, 'serializer': serializer}, template_name='list.html')

def retrieve(self, request, *args, **kwargs):
print(request.method, 'retrieve')
queryset = self.get_object()
serializer_class = SnippetSerializer(queryset, context={'request': request})
return Response({'queryset': queryset, 'serializer': serializer_class}, template_name='retrieve.html')

def create(self, request, *args, **kwargs):
print(request.method, 'create')
serializer = SnippetSerializer(instance=None, context={'request': request}, data=request.data)
if serializer.is_valid():
serializer.save(owner=self.request.user)
return redirect('snippet-list')

def post(self, request, *args, **kwargs):
print(request.method, 'post')
queryset = self.get_object()
serializer = SnippetSerializer(queryset, data=request.data, context={'request': request})
if not serializer.is_valid():
return Response({'serializer': serializer, 'queryset': queryset})
serializer.save()
return redirect('snippet-list')

def destroy(self, request, *args, **kwargs):
instance = self.get_object()
self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT)
def perform_destroy(self, instance):
instance.delete()

urls.py 保持不变:

snippet_list = SnippetViewSet.as_view({
'get': 'list',
'post': 'create',
})
snippet_detail = SnippetViewSet.as_view({
'get': 'retrieve',
'put': 'update',
'patch': 'partial_update',
'delete': 'destroy',
})
user_list = UserViewSet.as_view({ 'get': 'list'})
user_detail = UserViewSet.as_view({
'get': 'retrieve',
'put': 'update',
'patch': 'partial_update',
'delete': 'destroy'
})
urlpatterns = format_suffix_patterns([
url(r'^', snippet_list, name='snippet-list'),
url(r'^snippets/$', snippet_list, name='snippet-list'),
url(r'^snippets/(?P<pk>[0-9]+)$', snippet_detail, name='snippet-detail'),
url(r'^users/$', user_list, name='user-list'),
url(r'^users/(?P<pk>[0-9]+)/$', user_detail, name='user-detail'),
])

表单模板:

<form action="{% url 'snippet-detail' pk=queryset.pk %}" method="post">
{% csrf_token %}
{% render_form serializer %}
<input type="submit" value="Save">
<a href="{% url 'snippet-detail' pk=queryset.pk %}" methods="delete">delete</a>

单击删除按钮后,我所能得到的就是重新加载检索视图。除删除方法外的所有内容都可以正常工作。我知道我错过了一些小事,但如果你能指出我正确的方向,我将不胜感激。

问题是在对代码段详细信息 URL 的请求中使用delete方法来访问您的销毁视图。但是该方法不适用于 html 表单

因此,您需要另一种方式来访问此视图,例如:

snippet_destroy = SnippetViewSet.as_view({
'post': 'destroy',
})
urlpatterns = format_suffix_patterns([
url(r'^snippets/(?P<pk>[0-9]+)/delete$', snippet_destroy, name='snippet-delete'),
])

和使用

<form action="{% url 'snippet-delete' pk=queryset.pk %}" method="post">
{% csrf_token %}
<input type="submit" value="Delete">
</form>

您可能还希望销毁视图返回带有重定向到另一个 URL 的响应。


原答案:

您需要为两个操作使用一个表单,一个用于更新,一个用于删除。表单可以使用delete方法发出请求,而a标记不能。

<form action="{% url 'snippet-detail' pk=queryset.pk %}" method="post">
{% csrf_token %}
{% render_form serializer %}
<input type="submit" value="Save">
</form>
<form action="{% url 'snippet-detail' pk=queryset.pk %}" method="delete">
{% csrf_token %}
<input type="submit" value="Delete">
</form>

最新更新