如何通过pk过滤删除模型

How to delete model by filtering with pk

我正在尝试使用 pk 删除整个模型,但是当我点击“删除”时,我被重定向到给定页面但没有任何反应模型仍然存在并且没有被删除,但是当我写 '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(<strong>pk=pk</strong>).delete()
    return redirect('home')

但是您应该为 GET 请求执行此操作。删除项目应该通过 POST 请求或 DELETE 请求来完成。 As the W3 organization says:

In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered “safe”.

如果您接受 GET 请求,搜索引擎和某些已检索页面链接的浏览器可能会意外访问该视图,从而意外删除数据。

因此您应该限制 HTTP 方法:

from django.views.decorators.http import require_http_methods

<strong>@require_http_methods(['DELETE', 'POST'])</strong>
def delete_room(request, pk):
    Room.objects.filter(pk=pk).delete()
    return redirect('home')

对于 HTML 你应该制作一个像这样的迷你表格:

<form <strong>method="post"</strong> action="{% url 'delete_room' pk=room.pk %}">
    {% csrf_token %}
    <button <strong>type="submit"</strong> 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')