009-haLJl5Xj9Ys. using ajax post call in django
@
static/site.css
body{
padding-top: 60px;
padding-bottom: 60px;
}
@
static/jquery.csrf.js
# using jQuery
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
@
post_delete_confirm.html
# If post request is sent in same address, we don't need to fill action
@
_post_list.html
{% for post in post_list %}
{{ post.id }}
{{ post.title }}
# We will implement ajax delete request
# This method doesn't need to reload page
{{ post.title }}
# I make dynamic hyperlink with url named blog:post_detail and post.pk parameter
# I give this tag name of 'post-delete-btn'
delete post
@
models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
@
views.py
from django.http import JsonResponse
# I use built-in ListView, DetailView template for view
from django.views.generic import ListView, DetailView
# I use Post model in this view from all models
from .models import Post
from django.shortcuts import get_object_or_404, redirect, render
def post_list(request):
class AjaxListView(ListView):
def get_template_names(self):
if self.request.is_ajax():
app_label = self.object_list.model._meta.app_label
model_name = self.object_list.model._meta.model_name
return ['%s/_%s_list.html' % (app_label, model_name)]
return super(AjaxListView, self).get_template_names()
class AjaxJsonListView(ListView):
def render_to_response(self, context, **response_kwargs):
if self.request.is_ajax():
post_list = []
for post in context['post_list']:
post_list.append({
'id': post.id,
'title': post.title,
'content': post.content,
})
return JsonResponse(post_list, content_type='application/json', safe=False)
return super(AjaxJsonListView, self).render_to_response(context, **response_kwargs)
# I use AjaxJsonListView as view by using Post as model and showing 10 posts in one page
post_list = AjaxJsonListView.as_view(model=Post, paginate_by=10)
# I use DetailView as view by using Post as model
post_detail = DetailView.as_view(model=Post)
# If "ajax delete" url comes, "urls..py" captures it
# "urls..py" sends flow to this method
# with passing "request object" which has all information and "pk"
def post_delete(request, pk)
post = get_object_or_404(Post, pk=pk)
# If request is POST,
if request.method == 'POST':
# I actually delete post in jquery ajax way
post.delete()
# After delete, I redirect user to url named blog:post_list
return redirect('blog:post_list')
# If request is GET, I bring user to page to ask "really delete?"
return render(request, 'blog/post_delete_confirm.html', {
'post': post,
})
@
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
# I define this patter of url named 'post_list'
# which is used when creating dynamic url
url(r'^$', views.post_list, name = 'post_list'),
url(r'(?P\d+)/$', views.post_detail, name = 'post_detail'),
# This url mapping rule is for ajax delete
url(r'(?P\d+)/delete/$', views.post_delete, name = 'post_delete'),
]
@
urls.py (admin)
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include('blog.urls', namespace='blog')),
]
@
settings.py
INSTALLED_APPS=[
# ...
# This makes migration, template finding, etc possible
'blog'
]
STATIC_URL = '/static/'
# This is for jquery_csrf.js
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'ajax2nd', 'static'),
)
@
We will talk about POST ajax
You create new project
django-admin startproject ajax2nd
cd ajax2nd
python manage.py runserver
@
You create new app
python manage.py startapp blog
@
python manage.py migrate
python manage.py runserver
@
After building model, we perform migration
python manage.py makemigrations blog
python manage.py migrate blog
python manage.py run server
@
We create 1000 posts by using django shell
python manage.py shell
from blog.models import Post
for i in range(1000):
Post.objects.create(title = 'title {}'.format(i), content = 'content {}'.format(i))
# < title 1
# < content 1
Post.objects.all().count()
# < 1000
@
I need to make setting file for ajax post call
docs.djangoproject.com/en/1.9/ref/csrf
I create static/jquery.csrf.js
paste copied code into it