Adding object.id to render to string to avoid django.urls.exceptions.NoReverseMatch error

Viewed 25

I have a Django project that starts with a List view and when one of the objects are clicked it goes to a detailed view which has a button. When this button is clicked I am using Ajax to change a boolean from False to True value. So far I have reached to the point where when the button is clicked it changes the boolean in the backend using Ajax but the page still needs to be manually refreshed to show the effect of the boolean change. I am getting a No Reverse Match Error which can seem to solve it.

In my project I have a Detail view as following

class workout_details(DetailView):
    model = Workout
    template_name = 'my_gym/start_workout.html'
    context_object_name = 'workout'

def change_status(request, id):
    context = {}

    if request.is_ajax() and request.method == 'POST':
        startsession = Workout.objects.get(id=id)
        if request.POST.get('active') == 'true':
            startsession.active = True
            startsession.save()
            context.update({'status': 'success'})
            context.update({'active': str(startsession.active)})
        html = render_to_string('my_gym/start_workout.html', context)
        return JsonResponse({'form': html})

Here is the template my_gym/start_workout.html :

        <!-- button -->
            <div id="startworkout">
            {% include 'my_gym/button.html' %}
            </div>
        <!-- button -->

Here is the my_gym/button.html:

            <form action="{% url 'my_gym:bla' object.id %}" method='post'>
                {% csrf_token %}
                    {% if object.active %}
                    <button disabled  type="button">Start the workout</button>
                    {% else %}
                      <button value="true" id="customSwitches" onclick="start();" type="button">Start the workout</button>
                    {% endif  %}
            </form>
            <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>

            <script type="text/javascript">
                $(document).ready(function(event){
                    $(document).on('click','#customSwitches', function(event){
                        event.preventDefault();
                        var status= $(this).attr('value');
                        $.ajax({
                            type:'POST',
                            url:'{% url 'my_gym:bla' object.id %}',
                            data:{'active' : status, 'csrfmiddlewaretoken':'{{csrf_token}}'},
                            dataType:'json',
                            success:function(response){
                                $('#startworkout').html(response['form'])
                                console.log($('#startworkout').html(response['form']));
                            },
                            error:function(rs, e){
                                console.log(rs.responseText);
                            },
                        });
                    });
                });
            </script>

here is the views.py:

app_name = 'my_gym'

urlpatterns = [
    path('', home.as_view(), name='home'),
    path('workout/<int:pk>/', workout_details.as_view(), name='workout'),
    path('workout/bla/<int:id>/', change_status, name='bla'),
]

----------------UPDATE----------------

@SOM-1 gave comments which made me update the views to the following as it is missing context and now I getting an error in the terminal as Not Found: /workout/bla/1/

Here is the updated Views:

def change_status(request, id):
    if request.is_ajax() and request.method == 'POST':
        workout = get_object_or_404(Workout, id=request.POST.get('id'))
        if request.POST.get('active') == 'true':
            workout.active = True
            workout.save()
            context = {
                'status': 'success',
                'workout': workout,
            }
            html = render_to_string('my_gym/button.html', context)
            print("Sucess")
            return JsonResponse({'form': html})
        else:
            print("FAIL")
    else:
        print("FAIL")

None of the fail prints are being printed only NOT FOUND

1 Answers

Use {% url 'my_gym:bla' id=object.id %} instead of {% url 'my_gym:bla' object.id %}

Related