提问人:Erik Andersson 提问时间:7/14/2022 最后编辑:Sunderam DubeyErik Andersson 更新时间:7/14/2022 访问量:183
视图中删除功能的防御性编程 Django
Defensive programming for delete function in views Django
问:
我对 Django 还很陌生,我收到了一些关于我的项目(食谱应用程序)的反馈,我目前正在从我的导师那里得到一些关于防御性编程的反馈。我在 Django 的应用程序视图中创建了一个删除“函数”,他告诉我要重新制作该函数,这样除了食谱的作者之外,其他人都无法删除选定的食谱。我已经在我的 HTML 中包含了对此的身份验证,但他告诉我对我的删除视图做同样的事情。有没有人对我如何以简单的方式实现这一目标有一个很好的解释?
我以前从未在这里问过问题,所以如果我为这样的问题提供了正确的信息,请给我反馈。
这是我今天的删除视图:
def delete_recipe(request, slug):
"""
View for delete recipe
"""
recipe = Recipe.objects.get(slug=slug)
recipe.delete()
return redirect('home')
答:
我知道最好的描述,你该怎么做。它在这里:https://docs.djangoproject.com/en/4.0/topics/auth/default/#django.contrib.auth.decorators.permission_required
对于最佳实践,您应该检查用户是否具有 .object_delete_permission
@permission_required('app_name.delete_reciepe', login_url='/name_of_login_page/')
def delete_recipe(request, slug):
...
但这还不是全部:
之后,您应该检查这是否是产品的作者:
...
recipe = Recipe.objects.get(slug=slug)
if request.user.pk == recipe.author_pk
recipe.delete()
...
对我来说不清楚,为什么你不用 Django-GCBV 来做。https://docs.djangoproject.com/en/4.0/ref/class-based-views/generic-editing/#deleteviewDeleteView
这个视图在盒子里给你所有你需要的东西。
而且,当然,尝试仅在 POST 或 DELETE 时删除某些内容。
您应该只能使用 POST 或 DELETE 请求删除某些内容,而不能使用 GET 请求,因为 GET 请求应该不会产生副作用。我们可以用 @require_http_methods(...)
装饰器 [Django-doc] 来强制执行。
该视图还应确保用户已登录,方法是使用 @login_required
装饰器 [Django-doc]。
此外,您应该正确过滤,以便只有(或其他字段)可以删除 ,因此:author
Recipe
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
@require_http_methods(['DELETE', 'POST'])
@login_required
def delete_recipe(request, slug):
"""
View for delete recipe
"""
Recipe.objects.filter(slug=slug, author=request.user).delete()
return redirect('home')
然而,用户仍然可能需要权限才能删除 s,因为可以使用 @permission_required(...)
装饰器 [Django-doc]:Recipe
from django.contrib.auth.decorators import login_required, permission_required
from django.views.decorators.http import require_http_methods
@require_http_methods(['DELETE', 'POST'])
@login_required
@permission_required('app_name.delete_recipe')
def delete_recipe(request, slug):
"""
View for delete recipe
"""
Recipe.objects.filter(slug=slug, author=request.user).delete()
return redirect('home')
评论