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

202

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

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

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

Теги:

4 ответа

576
Лучший ответ

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

Django является серверной. Это означает, что клиент обращается к url, у вас есть функция внутри представлений, которая отображает то, что он видит, и возвращает ответ в 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 будет возвращать то же самое, что и в случае его посещения. Только на этот раз у вас есть функция js, и вы можете справиться с ней, как хотите. Рассмотрим простой пример:

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

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

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

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

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

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

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

  • 1
    Благодарю. Я просто был там, где ты, я знаю это чувство. Что касается чата - как правило, да, но не сейчас (также, для конкретных вопросов у вас есть ... ну ... в общем, ТАК).
  • 1
    PS у видео, которые я связал, есть целая неделя, посвященная AJAX. Серьезно, пройдите их. Они фантастические
Показать ещё 4 комментария
17

Кроме превосходного ответа 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

7

Простой и приятный. Вам не нужно менять свои взгляды. 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

  • 13
    Привет, быстрое примечание - я хочу посоветовать всем, кто только начинает изучать Django и \ или AJAX - пожалуйста , не используйте это. Вы ничему не научитесь. Держите его в избранном и создавайте запросы AJAX самостоятельно. Вернитесь и используйте Bjax, как только вы уже знакомы с тем, как он работает в фоновом режиме. Это не то же самое, что говорить людям изучать ассемблер для написания кода - вам не нужно создавать запросы AJAX с использованием чистого JS, просто jQuery, потому что если вы когда-нибудь захотите стать профессионалом, это минимальные базовые знания, которые вы должен иметь. ура
2

Я попытался использовать 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню