Как удалить модель путем фильтрации с помощью pk
Я пытаюсь удалить всю модель с помощью pk, но когда я нажимаю на "delete", я перенаправляюсь на данную страницу, но ничего не происходит, модель все еще там и не удаляется, но когда я пишу 'room_name' вместо 'pk', это работает, (спасибо заранее)
*Views.py:
def delete_room(request, pk):
Room.objects.filter(name=pk).delete()
return redirect('home')
Urls.py:
path("delete/<int:pk>/", views.delete_room, name="delete_room")
Models.py:
class Room(models.Model):
name = models.CharField(max_length=100)
about = models.TextField(max_length=500, null=True, blank=True)
creator = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, related_name='room_creator')
members = models.ManyToManyField(User, through="RoomMember")
class RoomMember(models.Model):
approved = models.BooleanField(default=False, blank=False)
room = models.ForeignKey(Room, related_name='memberships', on_delete=models.CASCADE)
user = models.ForeignKey(User, related_name='user_groups', on_delete=models.CASCADE)
class Messages(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=False, blank=False)
text = models.CharField(max_length=10000, blank=False, null=False)
date = models.DateTimeField(default=datetime.now)
room = models.ForeignKey(Room, null=True, blank=False, on_delete=models.CASCADE)
Html:
<a class="btn btn-danger" href="{% url 'delete_room' pk=room.pk %}">Delete Room</a>*
Вы можете фильтровать по первичному ключу pk
элемента, так:
def delete_room(request, pk):
Room.objects.filter(pk=pk).delete()
return redirect('home')
Но вы должны не делать это для GET-запроса. Удаление элементов должно осуществляться через POST-запрос или DELETE-запрос. Как говорит организация W3:
В частности, было установлено, что методы GET и HEAD НЕ ДОЛЖНЫ иметь значение для выполнения действий, отличных от извлечения. Эти методы должны считаться "безопасными".
Если вы принимаете GET-запросы, поисковые системы и некоторые браузеры, которые уже получают ссылки страницы, могут случайно посетить этот вид и таким образом случайно удалить данные.
Таким образом, вы должны ограничить методы HTTP с:
from django.views.decorators.http import require_http_methods
@require_http_methods(['DELETE', 'POST'])
def delete_room(request, pk):
Room.objects.filter(pk=pk).delete()
return redirect('home')
Для HTML вы должны сделать мини-форму следующего вида:
<form method="post" action="{% url 'delete_room' pk=room.pk %}">
{% csrf_token %}
<button type="submit" class="btn btn-danger">Delete Room</button>
</form>
В то время как ответ @Willem полностью устраивает, я также могу показать вам более простой и удобный для начинающих способ работы с методами запроса из объекта запроса.
def delete_room(request):
if request.method == "POST" or request.method == "DELETE":
#Handle your post and delete requests here
#e.g, deleting as was in the question
Room.objects.filter(pk=pk).delete()
#user will never get in here unless they hit via .delete or .post
#requests
return redirect('home')