fquivera
fquivera

Reputation: 15

modal form embedded in html does not work in django

I'm making an application for food recipes and am trying to do the same html in the recipe and include comments in a modal window, the problem is that when I give I submit template fails and does not save the comment on the data base

urls.py

urlpatterns = patterns('recetas.apps.menus.views',
    url(r'^recetas/$','recetas_view',name='vista_recetas'),
    url(r'^reporte/$','reporte_receta',name='receta_reporte'),
    url(r'^receta/(?P<id_receta>\d+)$','detalle_receta', name='vista_detalle'),
)

The html code that calls this url

<td><a href='/receta/{{ receta.id }}'>{{ receta.titulo }}</a></td>

views.py

def detalle_receta(request, id_receta):
    dato = get_object_or_404(Receta, pk=id_receta)
    comentarios = Comentario.objects.filter(receta=dato)
    if request.POST:
        if request.POST.get('cancel', id_receta):
            return HttpResponseRedirect('/receta/{0}'.format(id_receta))
        form = ComentarioForm(request.POST)
        if form.is_valid():
           form.save()
           return HttpResponseRedirect('/receta/{0}'.format(id_receta))
    else:
        form = ComentarioForm(initial={'receta': id_receta})

    cxt = {'receta':dato,'comentarios':comentarios,'form':form}
    return render_to_response('menus/receta.html', cxt, context_instance=RequestContext(request))

receta.html

{% extends 'base.html' %}
{% block titulo %}{{ receta.titulo }}{% endblock titulo %}
{% block estatico %}
<link rel='stylesheet' href='{{ STATIC_URL }}css/receta.css' type='text/css'>
<link rel='stylesheet' href='{{ STATIC_URL }}css/modal.css' type='text/css'>
<script type='text/javascript'>

    function despliegaModal(valor) {
        var elem = document.getElementById("bgVentanaModal");
        elem.style.visibility = valor;
        }
</script>
{% endblock estatico %}
{% block contenido %}
<div id="bgVentanaModal">
    <div id="ventanaModal">
        <form action="/receta/{{ receta.id_receta }}" method="POST">
            {% csrf_token %}
            {{ form.as_p }}
            <input type="submit" value="Grabar">
            <input name="cancel" type="submit" value="Cancelar">
        </form>
    </div>
</div>
<div id=receta>
    <div id="nombre_receta">
        <h1>{{receta.titulo|title}}</h1>
        <hr>
    </div>
    <div id='ingredientes'>
        <h2>Ingredientes</h2>
        <p>{{ receta.ingredientes }}</p>
    </div>
    <div id='imagen'>
        <img src='{{MEDIA_URL}}{{receta.imagen}}' width="480" height="300" >
    </div>
    <div id='preparacion'>
        <h2>Preparación</h2>
        <p>{{ receta.preparacion }}</p>
    </div>
    <div id='comentarios'>
        <h2>Comentarios</h2>
        {% for item in comentarios %}
            <p>{{ item.texto}}</p>
        {% empty %}
            <p>Sin Comentarios registrados</p>
        {% endfor %}
        {% if user.is_authenticated %}
            <a href="javascript:despliegaModal('visible');">Agregue su comentario</a>
        {% endif %}
    </div>
    <div id="pie">
        <hr>
        <p>Receta Registrada el {{ receta.tiempo_registro|date:'SHORT_DATETIME_FORMAT' }} por {{ receta.usuario }}</p>
    </div>
</div>
{% endblock contenido %}

everything works until I give the cancel key, does not validate the POST.

Upvotes: 1

Views: 369

Answers (2)

fquivera
fquivera

Reputation: 15

Thanks for help me Cesar, your answer help me, but my error is in the variable in receta.html

is {{ receta.id }} and in the button is the same the correct is

<form action="/receta/{{ receta.id }}" method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Grabar"/>
    <input type="button" value="Cancelar" onclick="window.location.href='/receta/{{ receta.id }}'"/>
</form>

Thanks for your help and a friend who found the error

Upvotes: 0

C&#233;sar
C&#233;sar

Reputation: 10119

I believe the problem is in your view.py. Specifically in this part:

if request.POST.get('cancel', id_receta):
    return HttpResponseRedirect('/receta/{0}'.format(id_receta))

That if will never result in a False value and, hence, your comment will never be saved. This has to do with how the dict.get function works:

get(key[, default])

Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.

So, if you click Grabar you'll get the default value (id_receta). Try the following instead:

if request.POST.get('cancel'): # Default to None
    return HttpResponseRedirect('/receta/{0}'.format(id_receta))

A workaround would be just using a button with some JavaScript to redirect when you click Cancelar in your template:

views.py

def detalle_receta(request, id_receta):
    dato = get_object_or_404(Receta, pk=id_receta)
    comentarios = Comentario.objects.filter(receta=dato)
    if request.POST:
        # if request.POST.get('cancel', id_receta):
        #    return HttpResponseRedirect('/receta/{0}'.format(id_receta))
        form = ComentarioForm(request.POST)
        if form.is_valid():
           form.save()
           return HttpResponseRedirect('/receta/{0}'.format(id_receta))
    else:
        form = ComentarioForm(initial={'receta': id_receta})

    cxt = {'receta':dato,'comentarios':comentarios,'form':form}
    return render_to_response('menus/receta.html', cxt, context_instance=RequestContext(request))

receta.html

...
...
<form action="/receta/{{ receta.id_receta }}" method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Grabar">
    <input type="button" value="Cancelar" onclick="window.location.href='/receta/{{ dato.id }}'"/>>
</form>
...
...

Of course, you should use get_absolute_url instead of hardcoding URLs.

Upvotes: 1

Related Questions