【问题标题】:Allowing users to delete their own comments in Django允许用户在 Django 中删除自己的评论
【发布时间】:2011-01-19 21:17:42
【问题描述】:

我正在使用 django.contrib.cmets.views.moderation 模块中的 delete() 函数。允许工作人员删除任何评论帖子,这完全没问题。但是,我还想授予注册编外人员删除他们自己的评论帖子的特权,并且只删除他们自己的评论帖子。我怎样才能做到这一点?

【问题讨论】:

    标签: python django django-comments


    【解决方案1】:

    如果您想将评论标记为已删除,就像django.contrib.comments.views.moderation.delete() 所做的那样:

    from django.contrib.auth.decorators import login_required
    from django.contrib.comments.models import Comment
    from django.shortcuts import get_object_or_404
    from django.conf import settings
    from django.contrib import comments
    
    @login_required
    def delete_own_comment(request, message_id):
        comment = get_object_or_404(comments.get_model(), pk=message_id,
                site__pk=settings.SITE_ID)
        if comment.user == request.user:
            comment.is_removed = True
            comment.save()
    

    【讨论】:

    • 我喜欢在这种情况下使用 Http404,因为如果有人在使用 URL,它几乎不会透露您的系统。 if comment.user != request.user: raise Http404 您还可以使用 get_object_or_404 来检索评论,如果在 URL 中发送了错误的 message_id,这比 500 错误更有意义。
    • 上面提到的例子几乎可以工作。我应该说我希望将 cmets 标记为删除,而不是实际删除 cmets。为此,我似乎需要发送一个 POST 请求。我如何发送 POST 请求而不是 GET?
    • 你不需要发送 POST,你可以模仿 comments 视图的作用;见编辑。
    • 好的,这几乎就是我想要的。我所要做的就是重新加载 HTTP_REFERER 而不是调试页面。 render_to_response 会是最好的吗?
    • HttpResponseRedirect 完成了这项工作。感谢您的帮助。
    【解决方案2】:

    我刚遇到这个问题。

    只需在 cmets 应用程序的删除视图中重新实现逻辑,即可将您的实现与该特定版本的 cmets 应用程序相结合。例如,当您将某些内容标记为已删除而提供的版本不这样做时,评论应用程序实际也会处理信号。

    幸运的是 cmets 应用程序提供了一个无需任何权限即可实现核心删除逻辑的功能。使用它会将你自己与内部细节联系起来,但它会以一种非常具体的方式这样做,要么会崩溃,要么会工作,它永远不会成功。您可以使用自己的安全模型创建自己的视图,然后调用提供的评论应用功能(来自 django.contrib.cmets.views.moderation import perform_delete)

    代码如下所示:

    @需要登录 def delete_my_comment(request, comment_id, next=None): 评论 = get_object_or_404(cmets.get_model(), pk=comment_id) 如果comment.user == request.user: 如果 request.method == "POST": perform_delete(请求,评论) 返回重定向(“您的视图”,comment.content_object.id) 别的: return render_to_response('cmets/delete.html', {'comment':评论,“下一个”:下一个}, 请求上下文(请求)) 别的: 提出Http404

    您的详细信息将根据您的用例而有所不同。

    我经历了一些变化(你可以在这个评论的历史中看到),我认为这个在所有方面都比这里提供的原始解决方案更好。

    【讨论】:

    • 同意。使用 'perform_delete' 是一个更好的解决方案,因为:1) 解耦实际的 cmets 删除逻辑。 2) perform_delete 实际上并没有删除,而是将评论标记为已删除。 3) perform_delete 触发 comment_was_flagged 信号,我用它来更新我们的搜索索引
    【解决方案3】:

    虽然这有点晚了,但你不能在模板中做同样的事情吗?

    {% if user == comment.user %}
      <a href="{% url comments-delete comment.id %}">delete comment</a> 
    {% endif %}
    

    这里使用django的cmets URL:

    url(r'^delete/(\d+)/$',  'moderation.delete',           name='comments-delete'),
    

    【讨论】:

    • 我也想过这个。但是,该删除功能需要用户具有删除评论权限。如果我授予每个普通用户删除任何评论的权限,我将遇到严重的安全问题。
    • 我最终使用了 {% if comment.name == user.username %}。此链接解释了原因 - stackoverflow.com/questions/61621950/…
    【解决方案4】:

    由于您在 HTML 中使用if request.method == 'POST':,因此您需要通过表单发送它,如下所示:

    <form action = "{% url 'comments-delete' %}" method = "POST">
        {% csrf_token %}
        <input type="hidden" name="comment_id" value="{{ comment.id }}"/>
        <input type="hidden" name="blogs_id" value="{{ blogs.id }}"/>
        <button>Delete</button>
    </form>
    

    views.py

    def delete_comment(request):
    id = request.POST['comment_id']
    pk = request.POST['blogs_id']
    if request.method == 'POST':
        comment = get_object_or_404(Comment, id=id, pk=pk)
        try:
            comment.delete()
            messages.success(request, 'You have successfully deleted the comment')
    
        except:
            messages.warning(request, 'The comment could not be deleted.')
    
    return redirect('get_posts')
    

    urls.py

    path('delete/comment/', delete_comment, name='delete_comment'),
    

    (使用 Django 2)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-03
      • 2013-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多