Ajax'ı Django uygulamalarıyla nasıl entegre edebilirim?


264

Django'da yeniyim ve Ajax'ta yeniyim. İkisini birleştirmem gereken bir proje üzerinde çalışıyorum. Her ikisinin de arkasındaki ilkeleri anladığımı düşünüyorum, ancak ikisinin birlikte iyi bir açıklaması bulamadım.

Birisi bana kod tabanı ikisi birlikte entegre ile nasıl değişmesi gerektiğini hızlı bir açıklama verebilir misiniz?

Örneğin, hala HttpResponseAjax ile kullanabilir miyim , yoksa yanıtlarım Ajax kullanımı ile değişmeli mi? Öyleyse, isteklere verilen yanıtların nasıl değişmesi gerektiğine ilişkin bir örnek verebilir misiniz? Herhangi bir fark yaratırsa, döndürdüğüm veriler JSON'dur.

Yanıtlar:


637

Bu tamamen SO ruhunda olmasa da, bu soruyu seviyorum, çünkü başladığımda aynı sorun yaşadım, bu yüzden size hızlı bir rehber vereceğim. Açıkçası, onların arkasındaki ilkeleri anlamıyorsunuz (bir suç olarak kabul etmeyin, ama eğer yaparsanız sormazsınız).

Django sunucu tarafındadır . Diyelim ki, bir müşteri bir URL'ye gidiyor, içinde viewsgördüklerini işleyen ve HTML'de yanıt döndüren bir fonksiyonunuz var . Örneklere ayıralım:

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

Bu, en basit kullanımlara bir örnektir. Gitmek 127.0.0.1:8000/hello, hello()işleve yönelik bir istek anlamına gelir , gidiş, tüm değişkenleri istendiği gibi 127.0.0.1:8000/homedöndürür index.htmlve değiştirir (muhtemelen bunları şimdiye kadar biliyorsunuzdur).

Şimdi AJAX hakkında konuşalım . AJAX çağrıları, eşzamansız istekler yapan istemci tarafı kodlardır. Kulağa karmaşık geliyor, ancak arka planda sizin için bir istekte bulunduğu ve ardından yanıtı ele aldığı anlamına geliyor. Dolayısıyla, bazı URL'ler için AJAX çağrısı yaptığınızda, kullanıcının o yere gitmesi ile aynı verileri alırsınız.

Örneğin, bir AJAX çağrısı, 127.0.0.1:8000/helloziyaret ettiğiniz gibi geri döndürülecektir. Sadece bu sefer, bir JavaScript işlevi içinde var ve istediğiniz gibi başa çıkabilirsiniz. Basit bir kullanım örneğine bakalım:

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

Genel süreç şudur:

  1. Çağrı, 127.0.0.1:8000/helloyeni bir sekme açıp kendiniz yaptığınız gibi URL'ye gider .
  2. Başarılı olursa (durum kodu 200), alınan verileri uyaran başarı işlevini yapın.
  3. Başarısız olursa, farklı bir işlev yapın.

Şimdi burada ne olurdu? İçinde 'merhaba dünya' yazan bir uyarı alırsınız. Eve AJAX çağrısı yaparsanız ne olur? Aynı şey, bir uyarı uyarısı alırsınız <h1>Hello world, welcome to my awesome site</h1>.

Başka bir deyişle - AJAX çağrıları hakkında yeni bir şey yok. Bunlar, kullanıcının sayfadan ayrılmadan veri ve bilgi almasına izin vermenin bir yoludur ve web sitenizin düzgün ve çok düzgün bir tasarımını sağlar. Dikkat etmeniz gereken birkaç kural:

  1. JQuery öğrenin . Bunu yeterince vurgulamıyorum. Aldığınız verilerin nasıl ele alınacağını bilmek için biraz anlamanız gerekecek. Ayrıca bazı temel JavaScript sözdizimini de anlamanız gerekir (python'dan çok uzak değil, buna alışacaksınız). Envato'nun jQuery için video eğitimlerini şiddetle tavsiye ediyorum, harikalar ve sizi doğru yola koyacaklar.
  2. JSON ne zaman kullanılır? . Django görünümleri tarafından gönderilen verilerin JSON'da olduğu birçok örnek göreceksiniz. Bununla ilgili ayrıntılara girmedim, çünkü nasıl yapılacağı önemli değil (bol miktarda açıklama var) ve ne zaman çok daha önemli . Ve bunun yanıtı - JSON verileri serileştirilmiş verilerdir. Yani, manipüle edebileceğiniz veriler. Bahsettiğim gibi, bir AJAX çağrısı yanıtı kullanıcı kendisi yapmış gibi cevap getirecektir. Şimdi tüm html ile uğraşmak istemediğinizi ve bunun yerine veri göndermek istediğinizi (belki de bir nesne listesi) söyleyin. JSON bunun için iyidir, çünkü onu bir nesne olarak gönderir (JSON verileri bir python sözlüğü gibi görünür) ve daha sonra bunu yineleyebilir veya işe yaramaz html yoluyla eleme ihtiyacını ortadan kaldıran başka bir şey yapabilirsiniz.
  3. Son ekleyin . Bir web uygulaması oluşturduğunuzda ve AJAX'ı uygulamak istediğinizde - kendinize bir iyilik yapın. İlk olarak, tüm uygulamayı tamamen herhangi bir AJAX'tan yoksun olarak oluşturun. Bakın her şey çalışıyor. Sonra ve ancak o zaman AJAX çağrılarını yazmaya başlayın. Bu da çok şey öğrenmenize yardımcı olan iyi bir süreç.
  4. Chrome'un geliştirici araçlarını kullanın . AJAX çağrıları arka planda yapıldığından bazen hata ayıklamak çok zordur. console.logHata ayıklamak için krom geliştirici araçlarını (veya kundakçı gibi benzer araçları) kullanmanız gerekir . Ben detaylı olarak açıklamayacağım, sadece google çevresinde ve hakkında bilgi. Size çok yardımcı olur.
  5. CSRF farkındalığı . Son olarak, Django'daki gönderi isteklerinin csrf_token. AJAX çağrılarıyla, sayfayı yenilemeden birçok kez veri göndermek istersiniz. Sonunda bunu hatırlamadan önce muhtemelen bir sorunla karşılaşacaksın - bekle, göndermeyi unuttun csrf_token. Bu, AJAX-Django entegrasyonunda bilinen bir başlangıç ​​barikatıdır, ancak nasıl güzel oynandığını öğrendikten sonra, pasta kadar kolaydır.

Kafama gelen her şey bu. Bu çok geniş bir konu, ama evet, muhtemelen yeterince örnek yok. Sadece oraya doğru çalış, yavaş yavaş, sonunda alacaksın.


1
Teşekkürler. Ben sadece senin olduğun yerde bulundum, hissi biliyorum. Sohbet gelince - genellikle evet, ama şu anda değil (ayrıca, belirli sorularınız için ... iyi ... SO'nun tamamı).
yuvi

2
PS bağladığım videolar AJAX adanmış bir hafta var. Cidden, onlardan geç. Onlar harika
yuvi

Bunun için teşekkürler @yuvi! Kendime AJAX hakkında aynı soruyu soruyorum. Dahası, AJAX'ı ne zaman kullanmam gerektiğinden emin değilim. Örneğin, Bootstrap kalıcı formlarını işlemek için bazı Javascript'e ihtiyacım olacağını anlıyorum, ancak AJAX ile ilişkili olup olmadığını anlamıyorum. Ve cidden, sayfamda bir pop-up görünmesi için tüm Jquery'yi öğrenmek zorunda kalmak ... Yatırımın geri dönüşünü göremiyorum :( Daha basit bir alternatif var mı? :( Cevabınız için tekrar teşekkürler.
David D.

5
@DavidW. Merhaba David, cevabımın size yardımcı olduğu için mutluyum. AJAX, basit javascript ile yapabileceğiniz, ancak çok karmaşık olabilen bir tekniktir. jQuery, çok daha kolay hale getiren kısayollara sahiptir. Bootstrap modalıyla bir ilgisi yok (isterseniz formları AJAX üzerinden getirebilirsiniz, ancak aksi halde ilgisizdir). Her neyse, yavaşça yolunu bulmaya çalışmanı şiddetle tavsiye ederim. jQuery bugünlerde önemli ve çok basit, çok iyi bir yatırım var. Birlikte gösterime bastığınızda SO'ya gelin ve sorun (burada zaten cevaplanmış bir sorunun yorumunda değil, yeni bir soru açın). İyi şanslar!
yuvi

Bahsettiğiniz konularla ilgili olarak csrf_token, bu yöntem üzerinde çalışabilir miyiz? Örnek bir fonksiyonumuz olsaydı ajaxCall(), sadece geleneksel bir yöntemi kullanabiliriz <form onsubmit='ajaxCall();return false;'>, değil mi?
ytpillai

22

Yuvanın mükemmel cevabından başka, Django içinde bununla nasıl başa çıkılacağına dair küçük bir spesifik örnek eklemek istiyorum (kullanılacak herhangi bir j'in ötesinde). Örnek AjaxableResponseMixinbir Yazar modeli kullanır ve varsayar.

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

Kaynak: Django belgeleri, Sınıf tabanlı görünümlerle form işleme

Django 1.6 sürümü bağlantısı artık 1.11 sürümüne güncelleştirilmemiştir


14

Bunu yazıyorum çünkü kabul edilen cevap oldukça eski, tazelenmeye ihtiyacı var.

Bu yüzden 2019'da Ajax'ı Django ile nasıl entegre edeceğim :) Ve Ajax'a ne zaman ihtiyacımız olduğuna dair gerçek bir örnek alalım: -

Kayıtlı kullanıcı adlarına sahip bir modelim olduğunu ve Ajax'ın yardımıyla belirli bir kullanıcı adının olup olmadığını bilmek istiyorum.

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)

Ayrıca render_to_response kaldırıldı ve ile ikame edilmiş olan işlemek ve Django 1.7 itibaren yerine gelen HttpResponse kullandığımız JsonResponse ajax yanıt. Bir JSON kodlayıcı ile birlikte geldiğinden, yanıt nesnesini döndürmeden önce verileri serileştirmeniz gerekmez HttpResponse, ancak kullanımdan kaldırılmaz.


8

Basit ve Güzel. Görüşlerinizi değiştirmek zorunda değilsiniz. Bjax tüm bağlantılarınızı yönetir. Şuna bir bak : Bjax

Kullanımı:

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

Son olarak, html'nizin HEAD'ına ekleyin:

$('a').bjax();

Daha fazla ayar için demoyu buradan kontrol edin: Bjax Demo


18
Merhaba, hızlı not - Django ve \ veya AJAX öğrenmeye yeni başlayan herkese tavsiye etmek istiyorum - lütfen bunu kullanmayın. Hiçbir şey öğrenemezsiniz. Favorilerinizde saklayın ve AJAX isteklerinizi kendiniz oluşturun. Geri dönün ve arka planda nasıl çalıştığını zaten bildiğinizde Bjax'ı kullanın. Bu, insanlara kodlama için Meclisi öğrenmelerini söylemek gibi değildir - AJAX isteklerinizi sadece jQuery ile oluşturmanıza gerek yoktur, çünkü profesyonel olmak istiyorsanız, bu temel bilgi ihtiyacı olmak. Şerefe
yuvi

5

AJAX zaman uyumsuz görevler yapmanın en iyi yoludur. Eşzamansız arama yapmak, herhangi bir web sitesi binasında yaygın olarak kullanılan bir şeydir. AJAX'ı Django'da nasıl uygulayabileceğimizi öğrenmek için kısa bir örnek alacağız. Daha az javascript yazmak için jQuery kullanmamız gerekiyor.

Bu en basit örnek olan İletişim örneğidir, AJAX'ın temellerini ve Django'daki uygulamasını açıklamak için kullanıyorum. Bu örnekte POST isteği yapacağız. Bu yazının bir örneğini takip ediyorum: https://djangopy.org/learn/step-up-guide-to-implement-ajax-in-django

models.py

Önce temel detayları içeren İletişim modelini oluşturalım.

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

Yukarıdaki model için form oluşturun.

from django import forms
from .models import Contact

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

views.py

Görünümler temel işlev tabanlı oluşturma görünümüne benzer, ancak render ile dönmek yerine JsonResponse yanıtı kullanıyoruz.

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

Yukarıdaki görünümün rotasını oluşturalım.

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

şablon

Ön uç bölümüne geçerek, form etiketini çevreleyen formun üzerinde oluşturulan formu csrf_token ile birlikte gönder ve gönder düğmesi. Jquery kütüphanesini eklediğimizi unutmayın.

<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

Şimdi javascript kısmı hakkında konuşalım, form gönderirken POST tipi ajax isteği yapıyoruz, form verilerini alıyor ve sunucu tarafına gönderiyoruz.

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

Bu sadece django ile AJAX ile başlamak için temel bir örnektir, birkaç örnekle dalış yapmak istiyorsanız, bu makaleyi inceleyebilirsiniz: https://djangopy.org/learn/step-up-guide-to- uygulamak-ajax-in-django


2

Projemde AjaxableResponseMixin kullanmaya çalıştım , ancak aşağıdaki hata iletisiyle karşılaştım:

Yanlış Yapılandırılmış: Yönlendirilecek URL yok. Bir url sağlayın veya Model üzerinde bir get_absolute_url yöntemi tanımlayın.

Çünkü tarayıcıya JSON isteği gönderdiğinizde CreateView bir HttpResponse döndürmek yerine bir yönlendirme yanıtı döndürecektir . Bu yüzden bazı değişiklikler yaptım AjaxableResponseMixin. İstek bir ajax isteğiyse, super.form_validyöntemi çağırmaz, form.save()doğrudan arayın .

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

0

Django kullandığımızda:

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

Eski verileri saklamak istiyorsanız, Ajax olmadan da yapabilirsiniz. (Sayfa yenilenecek)

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.

Veya Ajax ile yapabilirsiniz (Sayfa yenilenmeyecek)

--------------------------
<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 kullanıyorsanız şunları yapmanız gerekir:

  1. URL1'i kullanarak bir HTML sayfası başlatın (genellikle Django şablonuna göre ilk sayfayı oluştururuz). Ve sonra sunucu istemciye bir html sayfası gönderir.
  2. URL2 kullanarak sunucu ile iletişim kurmak için Ajax'ı kullanın. Ve sonra sunucu istemciye bir veri yapısı gönderir.

Django Ajax'tan farklı. Bunun nedeni şöyledir:

  • Müşteriye geri dönüş farklı. Django örneği HTML sayfasıdır. Ajax örneği veri yapısıdır. 
  • Django bir şey yaratmada iyidir, ancak sadece bir kez yaratabilir, hiçbir şeyi değiştiremez. Django anime gibidir, birçok resimden oluşur. Aksine, Ajax sth oluşturmada iyi değil, mevcut html sayfasında sth'yi değiştirme konusunda iyi.

Bence, her yerde ajax kullanmak isterseniz. önce veri içeren bir sayfa başlatmanız gerektiğinde, Django'yu Ajax ile kullanabilirsiniz. Ancak bazı durumlarda, sunucudan herhangi bir şey olmadan statik bir sayfaya ihtiyacınız vardır, Django şablonunu kullanmanız gerekmez.

Ajax'ın en iyi uygulama olduğunu düşünmüyorsanız. anime gibi her şeyi yapmak için Django şablonunu kullanabilirsiniz.

(İngilizcem iyi değil)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.