Bagaimana cara saya mengintegrasikan Ajax dengan aplikasi Django?

264

Saya baru mengenal Django dan cukup baru di Ajax. Saya sedang mengerjakan sebuah proyek di mana saya perlu mengintegrasikan keduanya. Saya percaya bahwa saya memahami prinsip-prinsip di belakang mereka berdua, tetapi belum menemukan penjelasan yang baik tentang keduanya.

Bisakah seseorang memberi saya penjelasan singkat tentang bagaimana basis kode harus berubah dengan mereka berdua terintegrasi bersama?

Misalnya, HttpResponseapakah saya masih dapat menggunakan dengan Ajax, atau apakah tanggapan saya harus berubah dengan penggunaan Ajax? Jika demikian, dapatkah Anda memberikan contoh bagaimana tanggapan terhadap permintaan harus berubah? Jika ada bedanya, data yang saya kembalikan adalah JSON.

tjons
sumber

Jawaban:

637

Meskipun ini tidak sepenuhnya dalam roh SO, saya suka pertanyaan ini, karena saya memiliki masalah yang sama ketika saya mulai, jadi saya akan memberi Anda panduan cepat. Jelas Anda tidak memahami prinsip-prinsip di belakang mereka (jangan menganggapnya sebagai pelanggaran, tetapi jika Anda melakukannya Anda tidak akan bertanya).

Django adalah sisi server . Artinya, katakanlah klien membuka URL, Anda memiliki fungsi di dalamnya viewsyang membuat apa yang dilihatnya dan mengembalikan respons dalam HTML. Mari kita bagi menjadi contoh:

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

Itu adalah contoh dari penggunaan paling sederhana. Pergi 127.0.0.1:8000/helloberarti permintaan ke hello()fungsi, 127.0.0.1:8000/homeakan mengembalikan index.htmldan mengganti semua variabel seperti yang diminta (Anda mungkin sudah tahu semua ini sekarang).

Sekarang mari kita bicara tentang AJAX . Panggilan AJAX adalah kode sisi klien yang melakukan permintaan asinkron. Kedengarannya rumit, tetapi itu berarti ia melakukan permintaan untuk Anda di latar belakang dan kemudian menangani respons. Jadi ketika Anda melakukan panggilan AJAX untuk beberapa URL, Anda mendapatkan data yang sama dengan yang Anda dapatkan ketika pengguna pergi ke tempat itu.

Misalnya, panggilan AJAX ke 127.0.0.1:8000/helloakan mengembalikan hal yang sama seperti jika Anda mengunjunginya. Hanya saja kali ini, Anda memilikinya di dalam fungsi JavaScript dan Anda bisa mengatasinya sesuka Anda. Mari kita lihat contoh penggunaan sederhana:

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

Proses umumnya adalah ini:

  1. Panggilan masuk ke URL 127.0.0.1:8000/helloseolah-olah Anda membuka tab baru dan melakukannya sendiri.
  2. Jika berhasil (kode status 200), lakukan fungsi untuk sukses, yang akan mengingatkan data yang diterima.
  3. Jika gagal, lakukan fungsi yang berbeda.

Sekarang apa yang akan terjadi di sini? Anda akan mendapatkan peringatan dengan 'hello world' di dalamnya. Apa yang terjadi jika Anda melakukan panggilan AJAX ke rumah? Hal yang sama, Anda akan mendapatkan peringatan yang menyatakan <h1>Hello world, welcome to my awesome site</h1>.

Dengan kata lain - tidak ada yang baru tentang panggilan AJAX. Mereka hanya cara bagi Anda untuk membiarkan pengguna mendapatkan data dan informasi tanpa meninggalkan halaman, dan itu membuat desain situs web Anda mulus dan sangat rapi. Beberapa pedoman yang harus Anda perhatikan:

  1. Pelajari jQuery . Saya tidak bisa cukup menekankan hal ini. Anda harus memahaminya sedikit untuk mengetahui bagaimana menangani data yang Anda terima. Anda juga perlu memahami beberapa sintaks dasar JavaScript (tidak jauh dari python, Anda akan terbiasa dengannya). Saya sangat merekomendasikan tutorial video Envato untuk jQuery , mereka sangat bagus dan akan menempatkan Anda di jalan yang benar.
  2. Kapan menggunakan JSON? . Anda akan melihat banyak contoh di mana data yang dikirim oleh pandangan Django di JSON. Saya tidak merinci hal itu, karena tidak penting bagaimana melakukannya (ada banyak penjelasan berlimpah) dan jauh lebih penting ketika . Dan jawabannya adalah - data JSON adalah data berseri. Yaitu, data yang dapat Anda manipulasi. Seperti yang saya sebutkan, panggilan AJAX akan mengambil respons seolah-olah pengguna melakukannya sendiri. Sekarang katakan Anda tidak ingin mengacaukan semua html, dan alih-alih ingin mengirim data (daftar objek mungkin). JSON baik untuk ini, karena mengirimkannya sebagai objek (data JSON terlihat seperti kamus python), dan kemudian Anda dapat beralih di atasnya atau melakukan sesuatu yang menghilangkan kebutuhan untuk menyaring html yang tidak berguna.
  3. Tambahkan yang terakhir . Ketika Anda membangun aplikasi web dan ingin menerapkan AJAX - bantulah diri Anda sendiri. Pertama, buat seluruh aplikasi sepenuhnya tanpa AJAX apa pun. Lihat bahwa semuanya berfungsi. Kemudian, dan baru setelah itu, mulailah menulis panggilan AJAX. Itu adalah proses yang baik yang membantu Anda belajar banyak juga.
  4. Gunakan alat pengembang chrome . Karena panggilan AJAX dilakukan di latar belakang, terkadang sangat sulit untuk melakukan debug. Anda harus menggunakan alat pengembang chrome (atau alat serupa seperti pembakar) dan console.loghal - hal untuk debug. Saya tidak akan menjelaskan secara detail, hanya google sekitar dan mencari tahu tentang hal itu. Ini akan sangat membantu Anda.
  5. Kesadaran CSRF . Akhirnya, ingat bahwa permintaan posting di Django memerlukan csrf_token. Dengan panggilan AJAX, sering kali Anda ingin mengirim data tanpa menyegarkan halaman. Anda mungkin akan menghadapi beberapa masalah sebelum akhirnya Anda mengingatnya - tunggu, Anda lupa mengirim csrf_token. Ini adalah penghalang bagi pemula yang dikenal dalam integrasi AJAX-Django, tetapi setelah Anda belajar cara membuatnya bermain bagus, mudah seperti pie.

Itu semua yang ada di kepalaku. Ini subjek yang luas, tapi ya, mungkin tidak ada cukup contoh di luar sana. Kerjakan saja di sana, perlahan-lahan, Anda akan mendapatkannya pada akhirnya

yuvi
sumber
1
Terima kasih. Aku hanya berada di tempatmu sekarang, aku tahu perasaan itu. Adapun chatting - umumnya ya, tetapi tidak sekarang (juga, untuk pertanyaan spesifik Anda memiliki ... baik ... keseluruhan SO)
yuvi
2
NB video yang saya tautkan memiliki satu minggu penuh didedikasikan untuk AJAX. Serius, telusuri mereka. Mereka luar biasa
yuvi
Terima kasih @yuvi untuk ini! Saya bertanya pada diri sendiri pertanyaan yang sama tentang AJAX. Terlebih lagi, saya tidak yakin kapan saya harus menggunakan AJAX atau tidak. Sebagai contoh, saya mengerti saya akan memerlukan beberapa Javascript untuk menangani bentuk modal Bootstrap tapi saya tidak mengerti apakah itu terkait dengan AJAX atau tidak. Dan serius, harus mempelajari seluruh Jquery hanya untuk membuat muncul pop-up di halaman saya ... Saya tidak dapat melihat laba atas investasi :( Apakah ada alternatif yang lebih sederhana? :( Terima kasih lagi atas jawaban Anda.
David D.
5
@ DavidW. Halo David, saya senang jawaban saya membantu Anda. AJAX adalah teknik, yang bisa Anda lakukan dengan javascript sederhana, tetapi bisa menjadi sangat rumit. jQuery hanya memiliki pintasan yang membuatnya jauh lebih mudah. Ini tidak ada hubungannya dengan modal Bootstrap (Anda dapat mengambil formulir melalui AJAX jika Anda mau, tetapi jika tidak, tidak terkait). Bagaimanapun, saya sangat menyarankan Anda mencoba dan mencari jalan perlahan. jQuery penting dan sangat mendasar akhir-akhir ini, jadi investasi yang bagus di sana. Ketika Anda mencapai penghalang jalan, datang ke SO dan tanyakan (tidak di sini di komentar dari pertanyaan yang sudah dijawab, buka yang baru). Semoga berhasil!
yuvi
Sehubungan dengan penyebutan Anda tentang csrf_token, bisakah kita mengatasi metode ini? Jika kita memiliki contoh fungsi, ajaxCall()kita bisa menggunakan metode tradisional seperti <form onsubmit='ajaxCall();return false;'>, kan?
ytpillai
22

Lebih jauh dari jawaban yuvi yang luar biasa, saya ingin menambahkan contoh spesifik kecil tentang bagaimana menangani hal ini dalam Django (di luar js yang akan digunakan). Contoh menggunakan AjaxableResponseMixindan mengasumsikan model Penulis.

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

Sumber: Dokumentasi Django, Penanganan formulir dengan tampilan berbasis kelas

Tautan ke versi 1.6 dari Django tidak lagi tersedia diperbarui ke versi 1.11

Wtower
sumber
14

Saya menulis ini karena jawaban yang diterima cukup lama, perlu penyegaran.

Jadi ini adalah bagaimana saya akan mengintegrasikan Ajax dengan Django pada tahun 2019 :) Dan mari kita ambil contoh nyata kapan kita membutuhkan Ajax: -

Katakanlah saya memiliki model dengan nama pengguna terdaftar dan dengan bantuan Ajax saya ingin tahu apakah nama pengguna yang diberikan ada.

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)

Juga render_to_response yang sudah usang dan telah digantikan oleh render dan dari Django 1.7 dan seterusnya, alih-alih HttpResponse kita menggunakan JsonResponse untuk respons ajax. Karena ia hadir dengan enkoder JSON, jadi Anda tidak perlu membuat serialisasi data sebelum mengembalikan objek respons tetapi HttpResponsetidak usang.

Ahtisham
sumber
8

Sederhana dan Bagus. Anda tidak harus mengubah pandangan Anda. Bjax menangani semua tautan Anda. Lihat ini: Bjax

Pemakaian:

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

Akhirnya, sertakan ini dalam KEPALA html Anda:

$('a').bjax();

Untuk pengaturan lebih lanjut, checkout demo di sini: Bjax Demo

bertahan
sumber
18
Halo, catatan singkat - Saya ingin memberi tahu siapa pun yang baru mulai mempelajari Django dan \ atau AJAX - tolong jangan gunakan ini. Anda tidak akan belajar apa-apa. Simpan di favorit Anda dan bangun permintaan AJAX Anda sendiri. Kembali dan gunakan Bjax begitu Anda sudah terbiasa dengan cara kerjanya di latar belakang. Ini tidak seperti menyuruh orang untuk belajar Assembly untuk kode - Anda tidak perlu membangun permintaan AJAX Anda dengan JS murni, cukup jQuery, karena jika Anda ingin menjadi seorang profesional, itu adalah pengetahuan dasar minimum yang akan Anda miliki perlu punya. Cheers
yuvi
5

AJAX adalah cara terbaik untuk melakukan tugas asinkron. Membuat panggilan tidak sinkron adalah sesuatu yang umum digunakan di setiap bangunan situs web. Kami akan mengambil contoh singkat untuk mempelajari bagaimana kami dapat mengimplementasikan AJAX di Django. Kita perlu menggunakan jQuery untuk menulis lebih sedikit javascript.

Ini adalah contoh Kontak , yang merupakan contoh paling sederhana, saya gunakan untuk menjelaskan dasar-dasar AJAX dan implementasinya di Django. Kami akan membuat permintaan POST dalam contoh ini. Saya mengikuti salah satu contoh posting ini: https://djangopy.org/learn/step-up-guide-to-implement-ajax-in-django

models.py

Pertama-tama mari kita buat model Kontak, memiliki detail dasar.

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

Buat formulir untuk model di atas.

from django import forms
from .models import Contact

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

views.py

Tampilan terlihat mirip dengan tampilan buat berbasis fungsi dasar, tetapi alih-alih kembali dengan render, kami menggunakan respons 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

Mari kita buat rute tampilan di atas.

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

templat

Pindah ke bagian frontend, render formulir yang dibuat di atas melampirkan tag formulir bersama dengan csrf_token dan tombol kirim. Perhatikan bahwa kami telah menyertakan perpustakaan 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

Sekarang mari kita bicara tentang bagian javascript, pada formulir kirim, kami membuat permintaan ajax dari tipe POST, mengambil data formulir dan mengirim ke sisi server.

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

Ini hanyalah contoh dasar untuk memulai dengan AJAX dengan Django, jika Anda ingin menyelam dengan beberapa contoh lagi, Anda dapat membaca artikel ini: https://djangopy.org/learn/step-up-guide-to- implement-ajax-in-django

Jai Singhal
sumber
2

Saya telah mencoba menggunakan AjaxableResponseMixin dalam proyek saya, tetapi berakhir dengan pesan kesalahan berikut:

Konfigurasi Tidak Benar: Tidak ada URL untuk dialihkan ke. Baik berikan url atau tentukan metode get_absolute_url pada Model.

Itu karena CreateView akan mengembalikan respons pengalihan alih-alih mengembalikan HttpResponse ketika Anda mengirim permintaan JSON ke browser. Jadi saya telah membuat beberapa perubahan pada AjaxableResponseMixin. Jika permintaan adalah permintaan ajax, itu tidak akan memanggil super.form_validmetode, panggil saja form.save()secara langsung.

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
Enix
sumber
0

Ketika kami menggunakan 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
----------------------------

Jika Anda ingin menyimpan data lama, Anda dapat melakukannya tanpa Ajax. (Halaman akan di-refresh)

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.

Atau Anda dapat melakukannya dengan Ajax (Halaman tidak akan di-refresh)

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

Jika Anda menggunakan Ajax, Anda harus melakukan ini:

  1. Inisial halaman HTML menggunakan URL1 (biasanya halaman awal oleh templat Django). Dan kemudian server mengirim halaman html kepada klien.
  2. Gunakan Ajax untuk berkomunikasi dengan server menggunakan URL2. Dan kemudian server mengirim klien data struct.

Django berbeda dari Ajax. Alasannya adalah sebagai berikut:

  • Hal kembali ke klien berbeda. Kasus Django adalah halaman HTML. Kasus Ajax adalah data struct. 
  • Django pandai menciptakan sesuatu, tetapi hanya bisa membuat sekali, tidak bisa mengubah apa pun. Django seperti anime, terdiri dari banyak gambar. Sebaliknya, Ajax tidak pandai menciptakan sth tetapi pandai mengubah sth di halaman html yang ada.

Menurut pendapat saya, jika Anda ingin menggunakan ajax di mana-mana. ketika Anda perlu menginisialisasi halaman dengan data pada awalnya, Anda dapat menggunakan Django dengan Ajax. Tetapi dalam beberapa kasus, Anda hanya perlu halaman statis tanpa apapun dari server, Anda tidak perlu menggunakan template Django.

Jika Anda tidak berpikir Ajax adalah praktik terbaik. Anda dapat menggunakan template Django untuk melakukan semuanya, seperti anime.

(Bahasa Inggris saya tidak bagus)

kyakya
sumber