用户只有在登录Django后才能发表评论

时间:2018-04-23 23:47:04

标签: django django-models django-forms django-templates django-views

我正在编写新闻网站,我希望用户只有在登录后才能提交新闻评论,如果没有,网站将返回login.html。

现在我已经确定只有已登录的用户才能提交评论,问题一旦我注销并提交评论错误说明:

Cannot assign "<SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x10fed10b8>>": "NewsComments.user" must be a "UserProfile" instance.

注意:我重写了用户模型并将其重命名为UserProfile。它运行良好。

这是我的新闻/ views.py:

def newsDetailView(request, news_pk):
    news = News.objects.get(id=news_pk)
    title = news.title
    author = news.author_name
    add_time = news.add_time
    content = news.content
    category = news.category
    tags = news.tag.annotate(news_count=Count('news'))

    all_comments = NewsComments.objects.filter(news=news)

    comment_form = CommentForm(request.POST or None)

    if request.method == 'POST' and comment_form.is_valid():
        comments = comment_form.cleaned_data.get("comment")
        comment = NewsComments(user=request.user, comments=comments, news=news)
        comment.save()

    return render(request, "news_detail.html", {
        'title': title,
        'author': author,
        'add_time': add_time,
        'content': content,
        'tags': tags,
        'category': category,
        'all_comments': all_comments,
        'comment_form': comment_form
    })

这是我的news.detail.html

            <form method="POST" action="">{% csrf_token %}
                <div class="form-group">
                    <label for="exampleFormControlTextarea1"><h5>评论 <i class="fa fa-comments"></i></h5></label>
                    <textarea id="js-pl-textarea" class="form-control" rows="4"
                              placeholder="我就想说..." name="comment"></textarea>
                    <div class="text-center mt-3">
                        <input type="submit" id='js-pl-submit' class="btn btn-danger comment-submit-button" value='Submit'>

                        </input>
                    </div>
                </div>
            </form>

这是我的urls.py:

path('-<int:news_pk>', newsDetailView, name="news_detail"),

3 个答案:

答案 0 :(得分:2)

您可以使用djangos login-required-decorator

@login_required
def newsDetailView(request, news_pk):
    ...

编辑从我的评论中扩展这个想法。

你可以有两个视图,一个带有login_required装饰器。 (如果您愿意,也可以使用class-based-views (CBV)

def view_news_details(request, news_pk):
    ...

@login_required
def post_comments(request, news_pk):
    ...

每个视图都有自己的网址:

url(r'^(?P<news_pk>[0-9]+)/$', views.view_news_details, name='view-details'),
url(r'^(?P<news_pk>[0-9]+)/comment/$', views.post_comments, name='comment'),

然后你可以使用只有一个模板但是使用条件渲染。此模板将由视图views.view_news_details呈现,但表单会将其数据发送到其他视图(请注意表单action属性)。

... display the news details here ...

{% if request.user.is_authenticated %}
    <form method="POST" action="{% url 'comment' news_instance.pk %}">
        ... here goes the content of the form ...
    </form>
{% endif %}

答案 1 :(得分:2)

将用户重定向到login view,然后让他在您的views.py中提交任何数据:

# Codes here 

if request.method == 'POST': # We separe those two "if statements", because
    # We want to redirect the user to login even if the form is not valid, User can bypass your security concern

    # For Django < 2.0, use it with () if request.user.is_authenticated():
    if request.user.is_authenticated:
        return redirect("login_url_name") # Or HttpResponseRedirect("login_url")
    if comment_form.is_valid():
        comments = comment_form.cleaned_data.get("comment")

        # Rest of codes

重要
在您的模板中,将表单的访问权限授予仅经过身份验证的用户

{% if request.user.is_authenticated %}

<form method="POST" action="">{% csrf_token %}
    <div class="form-group">
        <label for="exampleFormControlTextarea1"><h5>评论 <i class="fa fa-comments"></i></h5></label>
        <textarea id="js-pl-textarea" class="form-control" rows="4"
                          placeholder="我就想说..." name="comment"></textarea>
        <div class="text-center mt-3">
            <input type="submit" id='js-pl-submit' class="btn btn-danger comment-submit-button" value='Submit' />
         </div>
   </div>
</form>

{% endif %}

答案 2 :(得分:1)

您可以通过user.is_authenticated()方法检查所请求的用户是否已登录,该方法返回布尔值。
请尝试以下代码段,

def newsDetailView(request, news_pk):
    # code

    if request.method == 'POST' and comment_form.is_valid():
        if not request.user.is_authenticated():
            return HttpResponse("Please do login")
        comments = comment_form.cleaned_data.get("comment")
        comment = NewsComments(user=request.user, comments=comments, news=news)
        comment.save()

    return render(request, "news_detail.html", {
        'title': title,
        'author': author,
        'add_time': add_time,
        'content': content,
        'tags': tags,
        'category': category,
        'all_comments': all_comments,
        'comment_form': comment_form
    })