es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Enviar datos a la base de datos a través de fetch y posteriormente mostrar estos datos en una página HTML también a través de fetch, sin enviar el formulario o refrescar la página.

Tengo una aplicación de Django. Estoy escribiendo un comentario en un formulario y lo estoy enviando a mi base de datos mediante fetch.

Mi código js es el siguiente:

document.getElementById("comment-form").onsubmit = function write_comment(e) {
    e.preventDefault();
    const sxolio = document.getElementsByName("say")[0].value;

    fetch('/comment', {
        method: 'POST',
        body: JSON.stringify({
            say: sxolio
        })
    })
    .then(response => response.json())
    .then(result => {
        // Imprimir resultado
        console.log(result);
    });
};

Mis views.py:
@requires_csrf_token
@login_required(login_url='login')# Redirigir cuando el usuario no ha iniciado sesión
def comment(request):
    if request.method != 'POST':
        return JsonResponse({"error": "Se requiere una petición POST."}, status=400)
    new_comment = json.loads(request.body)
    say = new_comment.get("say", "")
    user = request.user
    comment = Comment(
        user = user,
        say = say,
        photo = Userimg.objects.get(user = user).image
    )
    comment.save()
    return JsonResponse({"message": "Comentario publicado."}, status=201);

Lo siguiente que quiero hacer es mostrar este comentario y todos los demás datos de mi base de datos en mi página HTML sin tener que refrescarla. En el momento en que presiono el botón de enviar, quiero que el comentario se muestre. No quiero actualizar la página con algún elemento.innerHTML = data.

Mi código js es el siguiente:

function display_comments() {
fetch(‘/all_comments’)
.then(response => response.json())
.then(all_comments => {
// Hacer algo con los comentarios
});
}

Mis views.py:
@login_required(login_url=’login’)# Redirigir cuando el usuario no ha iniciado sesión
def all_comments(request):
all_comments = Comment.objects.order_by(‘-date’).all()
print(all_comments[0].serialize())
return JsonResponse([comment.serialize() for comment in all_comments], safe=False)

Si uso preventDefault puedo ver que mi base de datos se actualiza, pero no puedo recuperar los datos.
Si omito preventDefault, todo funciona bien, pero la página se actualiza simultáneamente.
¿Existe alguna forma de hacer ambas cosas sin refrescar la página?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, puedes lograr esto utilizando AJAX para recuperar los datos actualizados del servidor sin actualizar toda la página.

    Primero, debes modificar tu función display_comments() para actualizar la página con el nuevo comentario sin recargarla. Aquí tienes un ejemplo de cómo puedes lograr esto utilizando jQuery:

    function display_comments() {
      $.ajax({
        url: '/all_comments',
        success: function (all_comments) {
          // Actualizar la página con el(los) nuevo(s) comentario(s)
          $('#comments-container').html(all_comments);
        },
      });
    }
    
    $(document).ready(function () {
      // Llamar a display_comments() después de que la página haya cargado
      display_comments();
    });
    
    // Llamar a display_comments() después de enviar el formulario
    $('#comment-form').on('submit', function (e) {
      e.preventDefault();
      const sxolio = $('input[name="say"]').val();
    
      $.ajax({
        url: '/comment',
        type: 'POST',
        data: JSON.stringify({ say: sxolio }),
        contentType: 'application/json',
        success: function (response) {
          // Mostrar un mensaje de éxito
          console.log(response);
    
          // Actualizar los comentarios
          display_comments();
    
          // Limpiar el formulario
          $('#comment-form')[0].reset();
        },
        error: function (error) {
          // Mostrar un mensaje de error
          console.error(error);
        },
      });
    });
    

    En el código anterior, estamos utilizando el método $.ajax() de jQuery para enviar una solicitud POST al servidor y recuperar el(los) nuevo(s) comentario(s) utilizando la función display_comments().

    Ten en cuenta que también estamos utilizando la función de devolución de llamada success para actualizar la página con el(los) nuevo(s) comentario(s) y limpiar el formulario después de un envío exitoso.

    También deberás modificar tu vista all_comments() para devolver una plantilla HTML en lugar de datos JSON. Aquí tienes un ejemplo:

    @login_required(login_url='login')
    def all_comments(request):
        all_comments = Comment.objects.order_by('-date').all()
        return render(request, 'comments.html', {'comments': all_comments})
    

    En el código anterior, estamos utilizando la función render() para renderizar una plantilla llamada 'comments.html' y pasar la consulta all_comments como una variable de contexto llamada 'comments'.

    Finalmente, deberás crear la plantilla comments.html para mostrar los comentarios. Aquí tienes un ejemplo:

    {% for comment in comments %}
      <div class="comment">
        <img src="{{ comment.photo.url }}" alt="{{ comment.user.username }}'s profile picture">
        <span class="username">{{ comment.user.username }}</span>
        <span class="date">{{ comment.date }}</span>
        {{ comment.say }}
      </div>
    {% empty %}
      No hay comentarios todavía.
    {% endfor %}
    

    En el código anterior, estamos utilizando el lenguaje de plantillas de Django para iterar sobre la consulta "comments" y mostrar cada comentario en un div 'comment'.

    Con estas modificaciones, tu aplicación de Django debería poder recuperar el(los) nuevo(s) comentario(s) del servidor sin actualizar la página después de un envío de formulario.

Comments are closed.