Как интегрировать Ajax с приложениями Django?

Я новичок в Django и довольно новичок в Ajax. Я работаю над проектом, где мне нужно интегрировать два. Я считаю, что понимаю принципы, лежащие в их основе, но не нашел хорошего объяснения этих двух.

Может ли кто-нибудь дать мне краткое объяснение того, как кодовая база должна измениться, когда они объединяются вместе?

Например, могу ли я использовать HttpResponse с Ajax, или мои ответы должны измениться с использованием Ajax? Если да, не могли бы вы привести пример того, как ответы на запросы должны измениться? Если это имеет значение, данные, которые я возвращаю, это JSON.

Ответ 1

Хотя это не совсем в духе ТАК, мне нравится этот вопрос, потому что у меня были те же проблемы, когда я начинал, поэтому я дам вам краткое руководство. Очевидно, вы не понимаете принципы, стоящие за ними (не воспринимайте это как оскорбление, но если бы вы это сделали, вы бы не спрашивали).

Джанго на стороне сервера. Это означает, что, скажем, клиент идет по URL, у вас есть функция внутри views которая отображает то, что он видит, и возвращает ответ в HTML. Позвольте разбить это на примеры:

views.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'),

Это пример простейшего использования. Переход к 127.0.0.1:8000/hello означает запрос к функции hello(), переход к 127.0.0.1:8000/home вернет index.html и заменит все переменные в соответствии с запросом (вы, наверное, уже все это знаете),

Теперь давайте поговорим об AJAX. AJAX-вызовы - это код на стороне клиента, выполняющий асинхронные запросы. Это звучит сложно, но это просто означает, что он выполняет запрос для вас в фоновом режиме, а затем обрабатывает ответ. Поэтому, когда вы делаете AJAX-вызов для какого-то URL, вы получаете те же данные, которые вы получаете, когда пользователь идет в это место.

Например, AJAX-вызов 127.0.0.1:8000/hello вернет то же самое, что и при посещении. Только на этот раз у вас есть это внутри функции JavaScript, и вы можете работать с ней так, как захотите. Давайте посмотрим на простой случай использования:

$.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');
    }
}); 

Общий процесс таков:

  1. Вызов переходит на URL 127.0.0.1:8000/hello как будто вы открыли новую вкладку и сделали это самостоятельно.
  2. Если это успешно (код состояния 200), выполните функцию успеха, которая предупредит полученные данные.
  3. Если не получается, сделайте другую функцию.

Что теперь будет здесь? Вы получите предупреждение с "Привет мир" в нем. Что произойдет, если вы сделаете AJAX звонок домой? То же самое, вы получите предупреждение о <h1>Hello world, welcome to my awesome site</h1>.

Другими словами - в вызовах AJAX нет ничего нового. Это просто способ дать пользователю возможность получать данные и информацию, не покидая страницу, и это обеспечивает плавный и очень аккуратный дизайн вашего сайта. Несколько рекомендаций, которые вы должны принять к сведению:

  1. Узнайте JQuery. Я не могу подчеркнуть это достаточно. Вам нужно немного это понять, чтобы понять, как обращаться с полученными вами данными. Вам также нужно понять некоторый базовый синтаксис JavaScript (недалеко от Python, вы привыкнете к нему). Я настоятельно рекомендую видеоуроки Envato для jQuery, они великолепны и помогут вам выбрать правильный путь.
  2. Когда использовать JSON? , Вы увидите много примеров, когда данные, отправляемые представлениями Django, находятся в формате JSON. Я не стал вдаваться в подробности, потому что не важно, как это сделать (имеется множество объяснений), и гораздо важнее, когда. И ответ на этот вопрос - данные JSON являются сериализованными данными. То есть данными, которыми вы можете манипулировать. Как я уже упоминал, AJAX-вызов будет получать ответ, как если бы пользователь сделал это сам. Теперь скажем, что вы не хотите связываться со всеми html файлами, а вместо этого хотите отправлять данные (возможно, список объектов). JSON хорош для этого, потому что он отправляет его как объект (данные JSON выглядят как словарь Python), а затем вы можете перебирать его или делать что-то еще, что устраняет необходимость просеивать бесполезный html.
  3. Добавьте это в последнюю очередь. Когда вы создаете веб-приложение и хотите внедрить AJAX - сделайте себе одолжение. Во-первых, создайте приложение полностью без AJAX. Смотри что все работает. Тогда и только тогда начните писать вызовы AJAX. Это хороший процесс, который также помогает вам многому научиться.
  4. Используйте инструменты разработчика Chrome. Поскольку вызовы AJAX выполняются в фоновом режиме, иногда их очень трудно отлаживать. Для отладки вы должны использовать инструменты разработчика chrome (или аналогичные инструменты, такие как firebug) и console.log. Я не буду подробно объяснять, просто погуглите и узнайте об этом. Это было бы очень полезно для вас.
  5. CSRF осведомленность. Наконец, помните, что для отправки сообщений в Django требуется csrf_token. С AJAX-вызовами вы часто отправляете данные без обновления страницы. Вы, вероятно, столкнетесь с некоторыми проблемами, прежде чем, наконец, вспомните это - подождите, вы забыли отправить csrf_token. Это известное препятствие для начинающих в интеграции AJAX-Django, но после того, как вы узнаете, как заставить его играть хорошо, это легко, как пирог.

Это все, что приходит мне в голову. Это обширная тема, но, да, там, наверное, недостаточно примеров. Просто прокладывайте себе путь, медленно, в конце концов, вы получите это.

Ответ 2

Кроме превосходного ответа yuvi, я хотел бы добавить небольшой конкретный пример того, как справиться с этим в Django (помимо любых js, которые будут использоваться). В примере используется AjaxableResponseMixin и предполагается модель автора.

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 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']

Источник: документация Django, обработка форм с использованием представлений на основе классов

Ссылка на версию 1.6 Django больше не обновляется до версии 1.11

Ответ 3

Простой и приятный. Вам не нужно менять свои взгляды. Bjax обрабатывает все ваши ссылки. Проверь это: Bjax

Использование:

<script src="bjax.min.js" type="text/javascript"></script>
<link href="bjax.min.css" rel="stylesheet" type="text/css" />

Наконец, включите это в HEAD вашего html:

$('a').bjax();

Для получения дополнительных настроек вы можете посмотреть демо: Демо-версия Bjax

Ответ 4

Я попытался использовать AjaxableResponseMixin в моем проекте, но в итоге появилось следующее сообщение об ошибке:

Неправильно Конфигурировано: нет URL-адреса для перенаправления. Либо укажите URL-адрес, либо определите метод get_absolute_url для модели.

Это потому, что CreateView вернет ответ перенаправления вместо возврата HttpResponse, когда вы отправляете запрос JSON в браузер. Поэтому я внес некоторые изменения в AjaxableResponseMixin. Если запрос является ajax-запросом, он не будет вызывать метод super.form_valid, просто вызовите form.save() напрямую.

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 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

Ответ 5

Я пишу это, потому что принятый ответ довольно старый, он нуждается в обновлении.

Вот так я бы интегрировал Ajax с Django в 2019 году :) И давайте возьмем реальный пример того, когда нам понадобится Ajax: -

Допустим, у меня есть модель с зарегистрированными именами пользователей, и с помощью Ajax я хочу узнать, существует ли данное имя пользователя.

HTML:

<p id="response_msg"></p> 
<form id="username_exists_form" method='GET'>
      Name: <input type="username" name="username" />
      <button type='submit'> Check </button>           
</form>   

Ajax:

$('#username_exists_form').on('submit',function(e){
    e.preventDefault();
    var username = $(this).find('input').val();
    $.get('/exists/',
          {'username': username},   
          function(response){ $('#response_msg').text(response.msg); }
    );
}); 

urls.py:

from django.contrib import admin
from django.urls import path
from . import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('exists/', views.username_exists, name='exists'),
]

views.py:

def username_exists(request):
    data = {'msg':''}   
    if request.method == 'GET':
        username = request.GET.get('username').lower()
        exists = Usernames.objects.filter(name=username).exists()
        if exists:
            data['msg'] = username + ' already exists.'
        else:
            data['msg'] = username + ' does not exists.'
    return JsonResponse(data)

Также render_to_response, который устарел и был заменен render и начиная с Django 1.7 и далее вместо HttpResponse, мы используем JsonResponse для ответа ajax. Поскольку он поставляется с кодировщиком JSON, вам не нужно сериализовывать данные перед возвратом объекта ответа, но HttpResponse не считается устаревшим.

Ответ 6

AJAX - лучший способ выполнять асинхронные задачи. Выполнение асинхронных вызовов является обычным делом при создании любого веб-сайта. Мы рассмотрим короткий пример, чтобы узнать, как мы можем реализовать AJAX в Django. Нам нужно использовать jQuery, чтобы писать меньше javascript.

Это контактный пример, который является самым простым примером, который я использую для объяснения основ AJAX и его реализации в Django. Мы будем делать запрос POST в этом примере. Я следую одному из примеров этого поста: https://djangopy.org/learn/step-up-guide-to-implement-ajax-in-django

models.py

Давайте сначала создадим модель контакта, имея базовые детали.

from django.db import models

class Contact(models.Model):
    name = models.CharField(max_length = 100)
    email = models.EmailField()
    message = models.TextField()
    timestamp = models.DateTimeField(auto_now_add = True)

    def __str__(self):
        return self.name

forms.py

Создайте форму для вышеуказанной модели.

from django import forms
from .models import Contact

class ContactForm(forms.ModelForm):
    class Meta:
        model = Contact
        exclude = ["timestamp", ]

views.py

Представления выглядят аналогично основному представлению создания на основе функций, но вместо возврата с визуализацией мы используем ответ JsonResponse.

from django.http import JsonResponse
from .forms import ContactForm

def postContact(request):
    if request.method == "POST" and request.is_ajax():
        form = ContactForm(request.POST)
        form.save()
        return JsonResponse({"success":True}, status=200)
    return JsonResponse({"success":False}, status=400)

urls.py

Давайте создадим маршрут вышеприведенного вида.

from django.contrib import admin
from django.urls import path
from app_1 import views as app1

urlpatterns = [
    path('ajax/contact', app1.postContact, name ='contact_submit'),
]

шаблон

Переходя к разделу внешнего интерфейса, визуализируйте форму, созданную над тегом формы, вместе с csrf_token и кнопкой отправки. Обратите внимание, что мы включили библиотеку jquery.

<form id = "contactForm" method= "POST">{% csrf_token %}
   {{ contactForm.as_p }}
  <input type="submit" name="contact-submit" class="btn btn-primary" />
</form>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Javascript

Давайте теперь поговорим о части JavaScript, при отправке формы мы делаем ajax-запрос типа POST, принимаем данные формы и отправляем на сервер.

$("#contactForm").submit(function(e){
    // prevent from normal form behaviour
        e.preventDefault();
        // serialize the form data  
        var serializedData = $(this).serialize();
        $.ajax({
            type : 'POST',
            url :  "{% url 'contact_submit' %}",
            data : serializedData,
            success : function(response){
            //reset the form after successful submit
                $("#contactForm")[0].reset(); 
            },
            error : function(response){
                console.log(response)
            }
        });
   });

Это просто базовый пример, чтобы начать работу с AJAX с django. Если вы хотите получить погружение с несколькими другими примерами, вы можете просмотреть эту статью: https://djangopy.org/learn/step-up-guide-to- реализовать-АЯКС-в-Джанго