Защитное программирование для функции delete в представлениях 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 DeleteView. https://docs.djangoproject.com/en/4.0/ref/class-based-views/generic-editing/#deleteview

Этот вид даст вам все, что нужно, в коробке.

И, конечно, попробуйте удалить что-то только по POST или DELETE.

You should only be capable to delete something with a POST or DELETE request, not with a GET request, since GET requests are supposed not to have side-effects. We can enforce this with the @require_http_methods(…) decorator [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')

Однако может быть и так, что пользователю требуется разрешение на удаление Recipe вообще, для этого можно использовать декоратор @permission_required(…) [Django-doc]:

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')
Вернуться на верх