python - por - ¿Cómo integro Ajax con las aplicaciones de Django?
login ajax django (4)
Además de la excelente respuesta de Yuvi, me gustaría agregar un pequeño ejemplo específico sobre cómo tratar esto dentro de Django (más allá de cualquier js que se usará). El ejemplo utiliza AjaxableResponseMixin
y asume un modelo de autor.
import json
from django.http import HttpResponse
from django.views.generic.edit import CreateView
from myapp.models import Author
class AjaxableResponseMixin(object):
"""
Mixin to add AJAX support to a form.
Must be used with an object-based FormView (e.g. CreateView)
"""
def render_to_json_response(self, context, **response_kwargs):
data = json.dumps(context)
response_kwargs[''content_type''] = ''application/json''
return HttpResponse(data, **response_kwargs)
def form_invalid(self, form):
response = super(AjaxableResponseMixin, self).form_invalid(form)
if self.request.is_ajax():
return self.render_to_json_response(form.errors, status=400)
else:
return response
def form_valid(self, form):
# We make sure to call the parent''s form_valid() method because
# it might do some processing (in the case of CreateView, it will
# call form.save() for example).
response = super(AjaxableResponseMixin, self).form_valid(form)
if self.request.is_ajax():
data = {
''pk'': self.object.pk,
}
return self.render_to_json_response(data)
else:
return response
class AuthorCreate(AjaxableResponseMixin, CreateView):
model = Author
fields = [''name'']
Fuente: documentación de Django, manejo de formularios con vistas basadas en clases.
El enlace a la versión 1.6 de Django ya no está disponible actualizado a la versión 1.11
Soy nuevo en Django y bastante nuevo en Ajax. Estoy trabajando en un proyecto donde necesito integrar los dos. Creo que entiendo los principios detrás de ambos, pero no he encontrado una buena explicación de los dos juntos.
¿Alguien podría darme una explicación rápida de cómo debe cambiar la base de código con los dos integrándose?
Por ejemplo, ¿puedo seguir usando HttpResponse
con Ajax, o tengo que cambiar mis respuestas con el uso de Ajax? Si es así, ¿podría dar un ejemplo de cómo deben cambiar las respuestas a las solicitudes? Si hay alguna diferencia, los datos que estoy devolviendo son JSON.
Aunque esto no está del todo en el espíritu SO, me encanta esta pregunta, porque tuve el mismo problema cuando comencé, así que te daré una guía rápida. Obviamente no entiendes los principios detrás de ellos (no lo tomes como una ofensa, pero si lo hicieras no lo preguntarías).
Django es del lado del servidor. Significa que, digamos que un cliente va a la URL, tiene una función dentro de las vistas que muestra lo que ve y devuelve una respuesta en html. vamos a dividirlo en ejemplos:
vistas.py
def hello(request):
return HttpResponse(''Hello World!'')
def home(request):
return render_to_response(''index.html'', {''variable'': ''world''})
index.html:
<h1>Hello {{ variable }}, welcome to my awesome site</h1>
urls.py
url(r''^hello/'', ''myapp.views.hello''),
url(r''^home/'', ''myapp.views.home''),
Ese es un ejemplo de los usos más simples. Ir a 127.0.0.1:8000/hello
significa una solicitud a la función de saludo, ir a 127.0.0.1:8000/home
devolverá el index.html
y reemplazará todas las variables según lo solicitado (probablemente ya sepa todo esto).
Ahora hablemos de AJAX. Las llamadas AJAX son códigos del lado del cliente que realizan solicitudes asíncronas. Eso suena complicado, pero simplemente significa que hace una solicitud por usted en segundo plano y luego maneja la respuesta. Entonces, cuando hace una llamada AJAX para obtener una URL, obtiene los mismos datos que obtendría cuando un usuario vaya a ese lugar.
Por ejemplo, una llamada ajax al 127.0.0.1:8000/hello
devolverá lo mismo que lo haría como si lo hubiera visitado. Solo que esta vez, la tienes dentro de una función js y puedes lidiar con ella como quieras. Veamos un caso de uso simple:
$.ajax({
url: ''127.0.0.1:8000/hello'',
type: ''get'', // This is the default though, you don''t actually need to always mention it
success: function(data) {
alert(data);
},
failure: function(data) {
alert(''Got an error dude'');
}
});
El proceso general es este:
- La llamada va al url
127.0.0.1:8000/hello
como si abrieras una nueva pestaña y lo hicieras tú mismo. - Si tiene éxito (código de estado 200), realice la función para el éxito, lo que alertará a los datos recibidos.
- Si falla, haz una función diferente.
Ahora, ¿qué pasaría aquí? Obtendrías una alerta con ''hola mundo'' en él. ¿Qué pasa si haces una llamada ajax a casa? Lo mismo, recibirá una alerta indicando <h1>Hello world, welcome to my awesome site</h1>
.
En otras palabras, no hay nada nuevo acerca de las llamadas AJAX. Son solo una forma de permitir que el usuario obtenga datos e información sin salir de la página, y permite un diseño suave y muy ordenado de su sitio web. Algunas pautas que debes tener en cuenta son:
- Aprende jQuery . No puedo enfatizar esto lo suficiente. Vas a tener que entenderlo un poco para saber cómo manejar los datos que recibes. También necesitarás entender alguna sintaxis javascript básica (no muy lejos de python, te acostumbrarás). Recomiendo encarecidamente los videos tutoriales de Envato para jQuery , son geniales y te pondrán en el camino correcto.
- ¿Cuándo usar JSON? . Verá muchos ejemplos en los que los datos enviados por las vistas de Django están en JSON. No entré en detalles sobre eso, porque no es importante cómo hacerlo (abundan las explicaciones) y mucho más importante cuando . Y la respuesta es: los datos JSON son datos serializados. Es decir, datos que puedes manipular. Como mencioné, una llamada AJAX buscará la respuesta como si el usuario lo hiciera él mismo. Ahora diga que no quiere meterse con todo el html, y en su lugar desea enviar datos (tal vez una lista de objetos). JSON es bueno para esto, porque lo envía como un objeto (los datos JSON parecen un diccionario de Python), y luego puede iterar sobre él o hacer otra cosa que elimine la necesidad de filtrar html inútiles.
- Añadirlo al final . Cuando creas una aplicación web y quieres implementar AJAX, hazte un favor. En primer lugar, cree la aplicación completa sin ningún AJAX. Ver que todo está funcionando. Entonces, y solo entonces, comienza a escribir las llamadas AJAX. Ese es un buen proceso que también te ayuda a aprender mucho.
- Usa las herramientas de desarrollo de Chrome . Dado que las llamadas AJAX se realizan en segundo plano, a veces es muy difícil depurarlas. Debes usar las herramientas de desarrollo de Chrome (o herramientas similares como firebug) y las cosas de console.log para depurar. No lo explicaré en detalle, solo busco un poco y lo averiguo. Sería muy útil para usted.
- Conciencia de CSRF . Finalmente, recuerde que las solicitudes de publicación en Django requieren el
csrf_token
. Con las llamadas AJAX, muchas veces le gustaría enviar datos sin actualizar la página. Probablemente enfrentará algunos problemas antes de que finalmente lo recuerde: espere, se olvidó de enviar elcsrf_token
. Este es un obstáculo conocido para principiantes en la integración AJAX-Django, pero después de que aprendas a hacer que funcione bien, es fácil como un pastel.
Eso es todo lo que viene a mi cabeza. Es un gran tema, pero sí, probablemente no haya suficientes ejemplos ahí fuera. Solo trabaja en tu camino, lentamente, lo conseguirás eventualmente.
He intentado usar AjaxableResponseMixin en mi proyecto, pero terminé con el siguiente mensaje de error:
Configurado incorrectamente: no hay URL a la que redireccionar. Proporcione una url o defina un método get_absolute_url en el modelo.
Esto se debe a que CreateView devolverá una respuesta de redirección en lugar de devolver una HttpResponse cuando envíe una solicitud JSON al navegador. Así que he hecho algunos cambios en el AjaxableResponseMixin
. Si la solicitud es una solicitud ajax, no llamará al método super.form_valid
, simplemente llame a form.save()
directamente.
from django.http import JsonResponse
from django import forms
from django.db import models
class AjaxableResponseMixin(object):
success_return_code = 1
error_return_code = 0
"""
Mixin to add AJAX support to a form.
Must be used with an object-based FormView (e.g. CreateView)
"""
def form_invalid(self, form):
response = super(AjaxableResponseMixin, self).form_invalid(form)
if self.request.is_ajax():
form.errors.update({''result'': self.error_return_code})
return JsonResponse(form.errors, status=400)
else:
return response
def form_valid(self, form):
# We make sure to call the parent''s form_valid() method because
# it might do some processing (in the case of CreateView, it will
# call form.save() for example).
if self.request.is_ajax():
self.object = form.save()
data = {
''result'': self.success_return_code
}
return JsonResponse(data)
else:
response = super(AjaxableResponseMixin, self).form_valid(form)
return response
class Product(models.Model):
name = models.CharField(''product name'', max_length=255)
class ProductAddForm(forms.ModelForm):
''''''
Product add form
''''''
class Meta:
model = Product
exclude = [''id'']
class PriceUnitAddView(AjaxableResponseMixin, CreateView):
''''''
Product add view
''''''
model = Product
form_class = ProductAddForm
Sencillo y agradable. No tienes que cambiar tus puntos de vista. Bjax maneja todos tus enlaces. Mira esto: Bjax
Uso:
<script src="bjax.min.js" type="text/javascript"></script>
<link href="bjax.min.css" rel="stylesheet" type="text/css" />
Finalmente, incluye esto en la CABEZA de tu html:
$(''a'').bjax();
Para más configuraciones, compruebe la demostración aquí: Demo Bjax