【问题标题】:How to delete model by filtering with pk如何通过 pk 过滤删除模型
【发布时间】:2021-12-29 14:21:25
【问题描述】:

我正在尝试使用 pk 删除整个模型,但是当我单击“删除”时,我被重定向到给定页面,但没有任何反应,模型仍然存在并且没有被删除,但是当我写了“房间名称”时'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>*

【问题讨论】:

  • 我觉得你需要Room.objects.filter(pk=pk).delete()
  • 太棒了!非常感谢,伙计
  • 这里的小写错误,您尝试的不是model,而是model instance,请记住您在模型中的模型转换为SQL中的完整表,那么是试图删除一个完整的表还是一个实例?只是收集你,但@voodoo-burger 的评论是完全正确的!
  • @JetEzra 感谢您的更正。所以我有一个名为 room 的模型,我试图只删除 1 个房间(用户看到删除按钮的当前房间)。

标签: python django django-models slug


【解决方案1】:

虽然@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')

【讨论】:

    【解决方案2】:

    你可以对item的主键pk进行过滤,所以:

    def delete_room(request, pk):
        Room.objects.filter(pk=pk).delete()
        return redirect('home')

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

    特别是,已经确立了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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-21
      • 1970-01-01
      • 2011-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多