Ajax
浏览器向网站发送请求时,URL 和 表单的形式提交,特点: 页面刷新
- GET
- POST
Ajax可以实现向后台偷偷发送请求
- 依赖JQuery
- 编写Ajax代码
简单示例:
-
task_list.html DOM方法绑定事件
{% extends 'layout.html' %}
{% block content %}
<div class=" container">
<h1>任务管理</h1>
<h2>示例1</h2>
<input type="button" class="btn btn-primary" value="点击" onclick="clickme();" />
</div>
{% endblock %}
{% block js %}
<script type="text/javascript">
function clickme() {
// console.log("点击了按钮");
$.ajax({
url:'/task/ajax/',
// type:"get",
type:"post",
data:{
n1: 123,
n2: 456
},
success: function (res) {
console.log(res);
}
})
}
</script>
{% endblock %}
-
task_list.html jquery 方法绑定事件
{% extends 'layout.html' %}
{% block content %}
<div class=" container">
<h1>任务管理</h1>
<h2>示例1</h2>
<input id="btn1" type="button" class="btn btn-primary" value="点击" />
</div>
{% endblock %}
{% block js %}
<script type="text/javascript">
$(function () {
// 当页面的框架加载完成之后,自动执行
bindBtnEvent1();
})
function bindBtnEvent1() {
$("#btn1").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
n1: 123,
n2: 456
},
success: function (res) {
console.log(res);
}
})
})
}
</script>
{% endblock %}
-
视图函数
# 任务管理 urls.py
# path('task/list/', task.task_list),
# path('task/ajax/', task.task_ajax),
# 前端\django\myweb\blog\views\task.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
def task_list(request):
"""任务列表"""
return render(request, 'task_list.html')
@csrf_exempt # 免除csrf认证可接收Post请求
def task_ajax(request):
"""Ajax 测试"""
print(request.GET) # <QueryDict: {'n1': ['123'], 'n2': ['456']}>
print(request.POST) # <QueryDict: {'n1': ['123'], 'n2': ['456']}>
return HttpResponse("ajax测试成功!")
Ajax 请求的返回值
-
一般都会返回JSON格式: 得到字符串 {status: true, data: [1, 2, 3, 4, 5]}
from django.shortcuts import render, redirect from django.http import HttpResponse,JsonResponse from django.views.decorators.csrf import csrf_exempt import json def task_list(request): """任务列表""" return render(request, 'task_list.html') @csrf_exempt # 免除csrf认证可接收Post请求 def task_ajax(request): """Ajax 测试""" # print(request.GET) # <QueryDict: {'n1': ['123'], 'n2': ['456']}> print(request.POST) # <QueryDict: {'n1': ['123'], 'n2': ['456']}> data_dict = {"status": True, 'data': [1, 2, 3, 4, 5]} # json_string = json.dumps(data_dict) # return HttpResponse(json_string) # return HttpResponse(json.dumps(data_dict)) return JsonResponse(data_dict)
- 使用 dataType: "JSON", 拿到字符json字符串后转换为前端的对象,就可以使用res取得对象的值
<script type="text/javascript"> $(function () { // 当页面的框架加载完成之后,自动执行 bindBtnEvent1(); }) function bindBtnEvent1() { $("#btn1").click(function () { $.ajax({ url: '/task/ajax/', type: "post", data: { n1: 123, n2: 456 }, dataType: "JSON", success: function (res) { console.log(res); console.log(res.status); console.log(res.data); } }) }) } </script>
Ajax 示例 提交数据
<div class=" container">
<h2>示例2-ajax提交数据</h2>
<input type="text" id="txtUser" placeholder="姓名" />
<input type="text" id="txtAge" placeholder="年龄" />
<input id="btn2" type="button" class="btn btn-primary" value="点击" />
</div>
<script type="text/javascript">
$(function () {
// 当页面的框架加载完成之后,自动执行
bindBtnEvent1();
bindBtnEvent2();
})
function bindBtnEvent2() {
$("#btn2").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
name: $("#txtUser").val(),
age: $("#txtAge").val(),
},
dataType: "JSON",
success: function (res) {
console.log(res);
console.log(res.status);
console.log(res.data);
}
})
})
}
</script>
Ajax 提交数据-form
<div class=" container">
<h2>示例3-ajax提交数据-form</h2>
<form id="form3">
<input type="text" name="user" placeholder="姓名" />
<input type="text" name="age" placeholder="年龄" />
<input type="text" name="email" placeholder="邮箱" />
<input type="text" name="more" placeholder="介绍" />
<input id="btn3" type="button" class="btn btn-primary" value="点击" />
</form>
</div>
<script type="text/javascript">
$(function () {
// 当页面的框架加载完成之后,自动执行
bindBtnEvent1();
bindBtnEvent2();
bindBtnEvent3();
})
function bindBtnEvent3() {
$("#btn3").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: $("#form3").serialize(),
dataType: "JSON",
success: function (res) {
console.log(res);
console.log(res.status);
console.log(res.data);
}
})
})
}
</script>
print(request.POST) # <QueryDict: {'user': ['tang'], 'age': ['18'], 'email': ['tang@tang.com'], 'more': ['hahaha']}>
Ajax 案例
-
前端\django\myweb\blog\models.py 创建表
# 管理员表
class Admin(models.Model):
"""管理员"""
username = models.CharField(verbose_name="用户名", max_length=32, unique=True)
password = models.CharField(verbose_name="密码", max_length=64)
def __str__(self):
return str(self.id) + ":" + str(self.username)
# 任务管理表
from django.db import models
class Task(models.Model):
"""任务"""
level_choices = (
(1, "紧急"),
(2, "重要"),
(3, "临时"),
)
level = models.SmallIntegerField(
verbose_name="级别", choices=level_choices, default=1)
title = models.CharField(verbose_name="标题", max_length=64)
detail = models.TextField(verbose_name="详细信息")
user = models.ForeignKey(verbose_name="负责人", to=Admin, to_field="username",
on_delete=models.SET_NULL, null=True, blank=False)
-
前端\django\myweb\blog\utils\form.py
# 任务管理
class TaskModelForm(BootStrapModelForm):
class Meta:
model = Task
fields = "__all__"
-
前端\django\myweb\blog\templates\task_list.html
<div class="panel-body">
<form id="form_add" class="form-group">
{% for field in form %}
<div class="form-group" style="position: relative;margin-bottom: 20px;">
<label>{{ field.label }}: </label>
{{ field }}
<span class="error-msg" style="color: red;position: absolute;"></span>
</div>
{% endfor %}
<div class="form-group">
<button id="btn_form" type="button" class="btn btn-success"><span class="glyphicon glyphicon-plus"
aria-hidden="true"></span><strong> 提 交</strong></button>
</div>
</form>
</div>
<script type="text/javascript">
$(function () {
// 当页面的框架加载完成之后,自动执行
bindBtnEvent1();
bindBtnEvent2();
bindBtnEvent3();
bindBtnAddEvent();
})
function bindBtnAddEvent() {
// $(".error_msg").text(""); 点击前错误信息置空
$(".error_msg").empty();
$("#btn_form").click(function () {
$.ajax({
url: '/task/add/',
type: "post",
data: $("#form_add").serialize(),
dataType: "JSON",
success: function (res) {
if (res.status) {
alert("添加成功!");
// 用JS实现页面的刷新
location.reload();
} else {
$.each(res.error, function (name,data){
// console.log(name, data);
$("#id_" + name).next().text(data[0])
})
}
}
})
})
}
</script>
-
前端\django\myweb\blog\views\task.py
@csrf_exempt # 免除csrf认证可接收Post请求
def task_add(request):
""" form add 测试"""
# print(request.POST) # <QueryDict: {'level': ['1'], 'title': ['代码库清理'], 'detail': ['代码库清理'], 'user': ['tang']}>
print(request.POST)
# 对用户发送过来的数据进行校验 (ModelForm进行校验)
form = TaskModelForm(data=request.POST)
if form.is_valid():
form.save()
data_dict = {"status": True}
return JsonResponse(data_dict)
# print(type(form.errors)) #<class 'django.forms.utils.ErrorDict'>
# print(form.errors) # <ul class="errorlist"><li>title<ul class="errorlist"><li>这个字段是必填项。</li></ul></li><li>detail<ul class="errorlist"><li>这个字段是必填项。</li></ul></li></ul>
# print(form.errors.as_json()) # {"title": [{"message": "\u8fd9\u4e2a\u5b57\u6bb5\u662f\u5fc5\u586b\u9879\u3002", "code": "required"}], "detail": [{"message": "\u8fd9\u4e2a\u5b57\u6bb5\u662f\u5fc5\u586b\u9879\u3002", "code": "required"}]}
# 可修改修改源码D:\python\Lib\site-packages\django\forms\utils.py 显示中文正常
# class RenderableErrorMixin(RenderableMixin):
# def as_json(self, escape_html=False):
# return json.dumps(self.get_json_data(escape_html),ensure_ascii=False)
# print(form.errors.as_text())
data_dict = {"status": False, 'error': form.errors}
return JsonResponse(data_dict)
# return HttpResponse(json.dumps(data_dict, ensure_ascii=False))
print(request.POST) # <QueryDict: {'level': ['1'], 'title': ['代码库清理'], 'detail': ['代码库清理'], 'user': ['tang']}
-
前端\django\myweb\blog\views\task.py 增加任务列表
def task_list(request):
"""任务列表"""
data_dict = {}
search_data = request.GET.get('q', "") # 有值拿值,没值为空
if search_data:
data_dict["title__contains"] = search_data
# print(request.GET.get)
# 分页函数封装
# from blog.utils.pagination import Pagination
queryset = Task.objects.filter(**data_dict).order_by("id")
# 初始化封装函数
page_obj = Pagination(request, queryset)
task_list = page_obj.page_queryset
# page_string, head_page, end_page = page_obj.html()
page_string = page_obj.html()
form = TaskModelForm()
context = {
"task_list": task_list,
"search_data": search_data,
"page_string": page_string,
"form": form
}
return render(request, 'task_list.html', context)
-
前端\django\myweb\blog\templates\task_list.html
<h2><strong>任务列表</strong></h2>
<div>
<form method="get" action="/task/list/">
<div class="input-group">
<input type="text" class="form-control" placeholder="查询任务标题" name="q" value="{{ search_data }}">
<span class="input-group-btn">
<button class="btn btn-primary" type="submit"><span class="glyphicon glyphicon-search"
aria-hidden="true"></span><strong> 搜索</strong></button>
</span>
</div>
</form>
</div>
<div style="margin-top: 20px;">
<div class="panel panel-default">
<div class="panel-heading">
<strong>
<span class="glyphicon glyphicon-th-list" aria-hidden="true"></span> 任务列表
</strong>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>标题</th>
<th>级别</th>
<th>负责人</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for iteam in task_list %}
<tr>
<th scope="row">{{ iteam.id }}</th>
<td>{{ iteam.title }}</td>
<td>{{ iteam.get_level_display }}</td>
<td>{{ iteam.user.username }}</td>
<td>
<a class="btn btn-primary btn-xs" href="/task/{{ iteam.id }}/edit/"> 编辑 </a>
<a class="btn btn-danger btn-xs" href="/task/del/?nid={{ iteam.id }}"> 删除 </a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<nav aria-label="page">
<ul class="pagination">
{{ page_string }}
<form method="get" action="/task/list/">
<div class="input-group col-sm-2" style="display: inline-block;margin-left: 20px;">
<span class="input-group-btn">
<input type="text" class="form-control" placeholder="页面跳转" name="page">
<button class="btn btn-primary" type="submit">>> 跳转</button>
</span>
</div>
</form>
</ul>
</nav>