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?
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: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óndisplay_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:En el código anterior, estamos utilizando la función
render()
para renderizar una plantilla llamada'comments.html'
y pasar la consultaall_comments
como una variable de contexto llamada'comments'
.Finalmente, deberás crear la plantilla
comments.html
para mostrar los comentarios. Aquí tienes un ejemplo: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.