我是Django的新手,Ajax的新手。我正在做一个项目,需要把两者结合起来。我相信我理解它们背后的原理,但还没有找到一个很好的解释两者结合。

有人能给我一个快速的解释,当它们两个集成在一起时,代码库必须如何改变?

例如,我仍然可以使用Ajax的HttpResponse,或者我的响应必须随着Ajax的使用而改变吗?如果是这样,您能否举例说明对请求的响应必须如何改变?如果它有任何不同,我返回的数据是JSON。


当前回答

除了yuvi的精彩回答之外,我还想添加一个关于如何在Django中处理这个问题的小具体示例(超出将使用的任何js)。该示例使用AjaxableResponseMixin并假设Author模型。

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

来源:Django文档,使用基于类的视图处理表单

Django 1.6版本的链接更新到1.11版本后不再可用

其他回答

我写这篇文章是因为公认的答案太老了,它需要更新。

这就是我在2019年将Ajax与Django集成的方式:)让我们举一个什么时候需要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>   

阿贾克斯:

$('#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()
        data['msg'] = username
        data['msg'] += ' already exists.' if exists else ' does not exists.'
    return JsonResponse(data)

render_to_response也被弃用了,从Django 1.7开始,我们使用JsonResponse来代替HttpResponse来进行ajax响应。因为它附带了一个JSON编码器,所以在返回响应对象之前不需要序列化数据,但是HttpResponse并没有弃用。

简单又漂亮。你不必改变你的观点。Bjax处理所有链接。看看这个: Bjax

用法:

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

最后,在你的html的HEAD中包含这个:

$('a').bjax();

欲了解更多设置,请在这里查看演示: Bjax演示

AJAX是执行异步任务的最佳方式。异步调用在任何网站建设中都很常见。我们将通过一个简短的例子来学习如何在Django中实现AJAX。我们需要使用jQuery来写更少的javascript。

这是一个接触的例子,这是最简单的例子,我用它来解释AJAX的基础知识和它在Django中的实现。在本例中,我们将发出POST请求。我引用了这篇文章中的一个例子:https://djangopy.org/learn/step-up-guide-to-implement-ajax-in-django

models.py

让我们首先创建Contact模型,其中包含基本细节。

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部分,在表单提交中,我们发出POST类型的ajax请求,获取表单数据并发送到服务器端。

$("#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)
            }
        });
   });

这只是一个开始使用django使用AJAX的基本示例,如果你想深入了解更多的示例,你可以阅读这篇文章:https://djangopy.org/learn/step-up-guide-to-implement-ajax-in-django

除了yuvi的精彩回答之外,我还想添加一个关于如何在Django中处理这个问题的小具体示例(超出将使用的任何js)。该示例使用AjaxableResponseMixin并假设Author模型。

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

来源:Django文档,使用基于类的视图处理表单

Django 1.6版本的链接更新到1.11版本后不再可用

当我们使用Django时:

Server ===> Client(Browser)   
      Send a page

When you click button and send the form,
----------------------------
Server <=== Client(Browser)  
      Give data back. (data in form will be lost)
Server ===> Client(Browser)  
      Send a page after doing sth with these data
----------------------------

如果希望保留旧数据,可以不使用Ajax。(页面会刷新)

Server ===> Client(Browser)   
      Send a page
Server <=== Client(Browser)  
      Give data back. (data in form will be lost)
Server ===> Client(Browser)  
      1. Send a page after doing sth with data
      2. Insert data into form and make it like before. 
      After these thing, server will send a html page to client. It means that server do more work, however, the way to work is same.

或者你可以用Ajax(页面不会刷新)

--------------------------
<Initialization> 
Server ===> Client(Browser) [from URL1]    
      Give a page                      
--------------------------  
<Communication>
Server <=== Client(Browser)     
      Give data struct back but not to refresh the page.
Server ===> Client(Browser) [from URL2] 
      Give a data struct(such as JSON)
---------------------------------

如果你使用Ajax,你必须做到这些:

使用URL1初始化一个HTML页面(我们通常使用Django模板初始化页面)。然后服务器发送一个html页面给客户端。 使用Ajax使用URL2与服务器通信。然后服务器端向客户端发送一个数据结构。

Django不同于Ajax。原因如下:

返还给客户的东西是不一样的。Django的案例是HTML页面。Ajax的案例是数据结构。 Django擅长创建一些东西,但它只能创建一次,它不能改变任何东西。姜戈就像一部动漫,由很多画面组成。相比之下,Ajax并不擅长创建,但擅长在现有的html页面中更改。

在我看来,如果你想到处使用ajax。当你需要用数据初始化页面时,你可以使用Django和Ajax。但在某些情况下,你只需要一个静态页面,不需要从服务器上获取任何东西,你不需要使用Django模板。

如果您认为Ajax不是最佳实践。你可以使用Django模板来做任何事情,比如动画。

(我的英语不好)