简体   繁体   中英

redirecting to comment section after login is not working in django

it saves and displays comments on the options.html page if the user is already logged in but when the user logs in after comment section redirects to the login page it displays the value error as this:
NoReverseMatch at /rank/best-trekking-destination-in-nepal/comment/
Reverse for 'comment' with arguments '('',)' not found. 1 pattern(s) tried: ['rank/(?P[^/]+)/comment/$']
Request Method: GET
Request URL: http://127.0.0.1:8000/rank/best-trekking-destination-in-nepal/comment/
Django Version: 2.1.5
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'comment' with arguments '('',)' not found. 1 pattern(s) tried: ['rank/(?P[^/]+)/comment/$']

urls.py

 path('<slug>/',views.options,name='options'),
 path('<slug>/comment/',views.comment,name='comment'),

views.py

def options(request,slug):
    category = Category.objects.get(slug=slug)
    category.views += 1
    category.save()
    options = category.option_set.all().order_by('-votes')
    try:
        for option in options:
            option.has_voted = option.vote_set.filter(voter=request.user).exists()
    except:
        options = category.option_set.all().order_by('-votes')


    form = CommentForm()
    return render(request, 'rank/options.html', {'options': options,'form':form,'title': 'options','category':category})



 @login_required(redirect_field_name='next',login_url='rank:login')
def comment(request,slug):
    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.category = Category.objects.get(slug=slug)
            comment.user = request.user
            comment.save()
            messages.success(request, 'Comment Posted.')
            return redirect('rank:options', slug)
    else:
        form = CommentForm()
    return render(request, 'rank/options.html', {'form': form})

def my_login(request):
    if request.method == "POST":
        form = LoginForm(request.POST)
        username = form['username'].value()
        password = form['password'].value()
        user = authenticate(username=username,password=password)
        if user:
            login(request,user)
            redirect_url = request.GET.get('next','rank:home')
            return redirect(redirect_url)
        else:
            messages.error(request,'Invaid Username or Password')

    else:
        form = LoginForm()
    return render(request,'rank/login.html',{'form':form})

options.html

{% extends "rank/base.html" %}
 <title>{% block title %}{{title}}{% endblock title%}</title>
{% load bootstrap4 %}
{% block content %}
<center><br>
     <ol type="1">
          <center>{% bootstrap_messages %}</center>
    {% for option in options %}

     <div class="col-lg-6 col-md-6 mb-6">
              <div class="card h-100">
                <div class="card-body">
                    <b><li>
                  <img src="/media/{{option.image}}" width="400" height="300">
                 <h4>{{option.name}}
                  </h4>
                  <h5 class="card-text">{{ option.details}}</h5>
                      <h5>{{ option.votes }} votes</h5>
                       {% if option.has_voted %}
                             <p class="btn btn-success">Voted</p>
                       {% else %}
                            <form action="{% url 'rank:vote' option.slug %}" method="post">
                           {% csrf_token %}
                       <input type="submit" class="btn btn-success" value="Vote" >
                       </form>
                       {% endif %}

                         </li></b>
                </div>
                <div class="card-footer">
                  <small class="text-muted"></small>
                </div>


              </div>
                </div>
         {% empty %}
    <div class="card w-100">
    <div class="card-body">
        <h4>Item not available</h4>
    </div>
    </div>

    {% endfor %}
     </ol>

<h3>{{ category.comment_set.all|length}} comments</h3>
    <hr>
            {% for c in category.comment_set.all %}
                  <div class="col-lg-6 col-md-6 mb-6">
                     <div class="card-footer text-muted">
                         <b>{{ c.user.username}} </b>&nbsp {{c.created|timesince}} ago
              </div>
              <div class="card-body">
                <p class="card-text">{{ c.comment}}</p>
              </div>

            </div>
            {% endfor %}

    <hr>
   <div class="col-lg-6 col-md-6 mb-6">
            <form method="post" action="{% url 'rank:comment' category.slug %}">
                {% csrf_token %}
            {% bootstrap_form form %}
            <input type="submit" class="btn btn-success" value="Post Comment">
            </form>
     </div>



</center>




{% endblock content%}

you comment function in views.py is incomplete. you don't handle GET and other types of request in there:

@login_required(redirect_field_name='next',login_url='rank:login')
def comment(request,slug):
    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.category = Category.objects.get(slug=slug)
            comment.user = request.user
            comment.save()
            messages.success(request, 'Comment Posted.')
            return redirect('rank:options',slug)   
    else:
        form = CommentForm()
    return render(request,'...some_template',{'form':form})

UPDATE : your next error NoReverseMatch is occured because vairable category (and also options ) not send from views to the options.html template and therefor it is null in the template ( arguments '('',)' not found ). you can fix that like this:

@login_required(redirect_field_name='next',login_url='rank:login')
def comment(request,slug):
   if request.method == "POST":
       form = CommentForm(request.POST)
       if form.is_valid():
           comment = form.save(commit=False)
           comment.category = Category.objects.get(slug=slug)
           comment.user = request.user
           comment.save()
           messages.success(request, 'Comment Posted.')
           return redirect('rank:options', slug)
   else:
       form = CommentForm()
   category = Category.objects.get(slug=slug)
   options = category.option_set.all().order_by('-votes')
   return render(request, 'rank/options.html', {'options': options,'form':form,'title': 'options','category':category})
@login_required(redirect_field_name='next',login_url='rank:login')
def comment(request,slug):
    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.category = Category.objects.get(slug=slug)
            comment.user = request.user
            comment.save()
            messages.success(request, 'Comment Posted.')
            return redirect('rank:options',slug)

    return redirect('some default view')

You need to add a view to each branch of computation if your POST request view fails or the form is not valid then a view is not returned. I put a line of code you need to finish off.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM