私はDjangoに慣れていないし、Ajaxについてはかなり新しいです。私は2つを統合する必要があるプロジェクトに取り組んでいます。私は両方の背後にある原則を理解していると思いますが、この2つの良い説明を一緒に見つけていません。
2人が一緒に統合したときにコードベースがどのように変更される必要があるかについて、誰かが私に簡単に説明してもらえますか?
たとえば、AjaxでHttpResponse
を使用することはできますか。それとも、Ajaxを使用することで回答を変更する必要がありますか。もしそうなら、あなたは要求への応答がどのように変化しなければならないかの例を教えてください。違いがある場合、私が返すデータはJSONです。
これは完全にはSOの精神ではありませんが、私はこの質問が大好きです、なぜなら私は始めたとき私が同じ悩みを抱えていたので、私はあなたにクイックガイドをあげるでしょう。明らかにあなたはそれらの背後にある原則を理解していません(それを違法と見なさないでください、しかしあなたがそうしたならあなたは尋ねることはないでしょう)。
Djangoはサーバーサイドです。つまり、クライアントが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呼び出しは、非同期要求を実行するクライアント側のコードです。それは複雑に聞こえますが、それは単にそれがバックグラウンドであなたのためにリクエストをしてそれからレスポンスを処理することを意味します。したがって、あるURLに対してAJAX呼び出しを実行すると、ユーザーがその場所にアクセスしたときと同じデータが取得されます。
たとえば、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');
}
});
一般的なプロセスはこれです:
127.0.0.1:8000/hello
に移動します。今ここで何が起こるでしょうか?あなたはその中に「こんにちは世界」と警告を受けるでしょう。あなたが家にAJAX電話をかけるとどうなりますか?同じこと、<h1>Hello world, welcome to my awesome site</h1>
という警告が表示されるでしょう。
言い換えれば - AJAX呼び出しについて新しいことは何もありません。それらはあなたがページを離れることなくユーザーにデータと情報を手に入れることを可能にするためのちょうど方法であり、そしてそれはあなたのウェブサイトの滑らかで非常にきれいなデザインに役立ちます。注意すべきガイドラインがいくつかあります。
console.log
のものを使用してください。私は詳細に説明するのではなく、ただグーグルの周りでそれについて調べる。それはあなたにとって非常に役に立つでしょう。csrf_token
が必要であることを忘れないでください。 AJAX呼び出しでは、ページを更新せずにデータを送信したいことがよくあります。最後に覚えておく前に、おそらく何らかのトラブルに直面するでしょう - 待って、あなたはcsrf_token
を送るのを忘れていました。これはAJAX-Djangoの統合における既知の初心者の障害ですが、あなたがそれを素晴らしいものにする方法を学んだ後、それはパイのように簡単です。それが私の頭に浮かんだすべてです。それは広大な主題ですが、ええ、おそらくそこに十分な例はありません。ゆっくりとそこに向かって進むだけで、最終的にはうまくいくでしょう。
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'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年にDjangoにAjaxを統合する方法です:)そして、私たちが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()
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 ではなくajaxレスポンスに JsonResponse を使います。 JSONエンコーダが付属しているので、レスポンスオブジェクトを返す前にデータをシリアル化する必要はありませんが、HttpResponse
name__は推奨されません。
AJAXは非同期タスクを実行するための最良の方法です。非同期呼び出しを行うことは、どのWebサイト構築でも一般的に使用されていることです。 DjangoでAJAXを実装する方法を学ぶために短い例を取ります。 javascriptを少なくするためにjQueryを使う必要があります。
これはContactの例です。これは最も簡単な例です。私は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
ビューは基本的な関数ベースのcreateビューに似ていますが、renderで返される代わりに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および送信ボタンと共に、囲むformタグの上に作成されたフォームをレンダリングします。 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/) ajax-in-Djangoを学ぶ/ステップアップするためのガイド
私は自分のプロジェクトで AjaxableResponseMixin を使用しようとしましたが、次のエラーメッセージが表示されました。
ImproperlyConfigured:リダイレクト先のURLがありません。モデルにURLを指定するか、get_absolute_urlメソッドを定義します。
これは、JSON要求をブラウザに送信するときに、CreateViewがHttpResponseを返す代わりにリダイレクト応答を返すためです。だから私は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'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