Ajax
浏览器向网站发送请求时,URL 和 表单的形式提交
- GET
- POST
特点: 页面刷新
Ajax可以实现向后台偷偷发送请求
- 依赖JQuery
- 编写Ajax代码
$.ajax({
url:"发送的地址",
type: "get",
data:{
n1:123,
n2:456
},
success:function(res){
console.log(res);
}
})
GET请求
新建myproject/employee_management/views/task.py
from django.shortcuts import render,HttpResponse
def task_list(request):
return render(request, "task_list.html")
def task_ajax(request):
print(request.GET)
return HttpResponse("成功了")
修改myproject/myproject/urls.py
# 任务管理
path('task/list/', task.task_list),
path('task/ajax/', task.task_ajax),
新建myproject/employee_management/templates/task_list.html
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<h1>任务管理</h1>
<h3>示例1</h3>
<input type="button" value="点击" class="btn btn-primary" onclick="clickMe();">
</div>
{% endblock %}
{% block script %}
<script type="text/javascript">
function clickMe() {
$.ajax({
url: '/task/ajax/',
type: "get",
data: {
n1:123,
n2:456
},
success: function(res) {
console.log(res);
}
})
}
</script>
{% endblock %}
修改myproject/employee_management/templates/layout.html
<li><a href="/task/list/">任务管理</a></li>
...
{% block script %}
{% endblock %}
POST请求
修改myproject/employee_management/views/task.py
csrf_exempt可以免除在HTM中写CSRF
from django.shortcuts import render,HttpResponse
from django.views.decorators.csrf import csrf_exempt
def task_list(request):
return render(request, "task_list.html")
@csrf_exempt
def task_ajax(request):
print("get请求: ", request.GET)
print("post请求: ", request.POST)
return HttpResponse("成功了")
修改myproject/employee_management/templates/task_list.html
浏览器访问测试,F12依然开启调试模式
查看后台输出
对上面的Ajax代码进行优化:
绑定事件
修改myproject/employee_management/templates/task_list.html
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<h1>任务管理</h1>
<h3>示例1</h3>
<input id="btn1" type="button" value="点击" class="btn btn-primary">
</div>
{% endblock %}
{% block script %}
<script type="text/javascript">
$(function () {
// 页面框架加载完成之后代码自动执行
bindBtn1Event();
})
function bindBtn1Event() {
$("#btn1").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
n1: 123,
n2: 456
},
success: function (res) {
console.log(res);
}
})
})
}
</script>
{% endblock %}
返回值
以JSON的方式返回数据
修改myproject/employee_management/templates/task_list.html
function bindBtn1Event() {
$("#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);
}
})
})
}
实现后台接收
输入框
中的内容
修改myproject/employee_management/templates/task_list.html
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<h1>任务管理</h1>
<h3>示例1</h3>
<input id="btn1" type="button" value="点击" class="btn btn-primary">
<h3>示例2</h3>
<input type="text" id="txtuser" placeholder="姓名">
<input type="text" id="txtpwd" placeholder="密码">
<input id="btn2" type="button" value="点击" class="btn btn-primary">
</div>
{% endblock %}
{% block script %}
<script type="text/javascript">
$(function () {
// 页面框架加载完成之后代码自动执行
bindBtn1Event();
bindBtn2Event();
})
function bindBtn1Event() {
$("#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);
}
})
})
}
function bindBtn2Event() {
$("#btn2").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
name: $("#txtuser").val(),
password: $("#txtpwd").val()
},
dataType: "JSON",
success: function (res) {
console.log(res);
console.log(res.status);
console.log(res.data);
}
})
})
}
</script>
{% endblock %}
假如前端代码过多,我们需要用更简单的方法批量处理
修改myproject/employee_management/templates/task_list.html
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<h1>任务管理</h1>
<h3>示例1</h3>
<input id="btn1" type="button" value="点击1" class="btn btn-primary">
<h3>示例2</h3>
<input type="text" id="txtuser" placeholder="姓名">
<input type="text" id="txtpwd" placeholder="密码">
<input id="btn2" type="button" value="点击2" class="btn btn-primary">
<form id="from3">
<h3>示例2</h3>
<input type="text" name="user" placeholder="姓名">
<input type="text" name="age" placeholder="年龄">
<input type="text" name="pwd" placeholder="密码">
<input type="text" name="mobile" placeholder="电话">
</form>
<input id="btn3" type="button" value="点击3" class="btn btn-primary">
</div>
{% endblock %}
{% block script %}
<script type="text/javascript">
$(function () {
// 页面框架加载完成之后代码自动执行
bindBtn1Event();
bindBtn2Event();
bindBtn3Event();
})
function bindBtn1Event() {
$("#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);
}
})
})
}
function bindBtn2Event() {
$("#btn2").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
name: $("#txtuser").val(),
password: $("#txtpwd").val()
},
dataType: "JSON",
success: function (res) {
console.log(res);
console.log(res.status);
console.log(res.data);
}
})
})
}
function bindBtn3Event() {
$("#btn3").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: $("#from3").serialize(),
dataType: "JSON",
success: function (res) {
console.log(res);
console.log(res.status);
console.log(res.data);
}
})
})
}
</script>
{% endblock %}
这样,我们就学会了如何在浏览器页面不刷新的情况下,如何向后台提交数据
接下来正式开始Ajax的案例
任务添加(一)
首先为该页面创建一个表
编辑myproject/employee_management/models.py
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, on_delete=models.CASCADE)
更新信息
python3 manage.py makemigrations
python3 manage.py migrate
编辑myproject/employee_management/views/task.py
from employee_management.utils.modelform import BootStrapModelForm
from employee_management.models import Task
class TaskModelForm(BootStrapModelForm):
class Meta:
model = Task
fields = "__all__"
@csrf_exempt
def task_list(request):
form = TaskModelForm()
return render(request, "task_list.html", {"form": form})
编辑myproject/employee_management/templates/task_list.html
<div class="panel panel-default">
<div class="panel-heading">表单</div>
<div class="panel-body">
<form method="post" novalidate>
{% for item in form %}
<div class="form-group">
<label>{{ item.label }}</label>
{{ item }}
</div>
{% endfor %}
</form>
</div>
</div>
浏览器访问
但是会有一个问题存在
解决办法:编辑myproject/employee_management/models.py
def __str__(self):
return self.username
class Admin(models.Model):
"""管理员"""
username = models.CharField(verbose_name="用户名", max_length=32)
password = models.CharField(verbose_name="密码", max_length=64)
def __str__(self):
return self.username
接下来实现将添加的数据发送到后台
优化一下前端的展示样式
编辑myproject/employee_management/templates/task_list.html
注意: 下面前端代码中的
button
标签必须放在form
表单的外面,不然submit
的 Ajax 触发机制不会生效
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">表单</div>
<div class="panel-body">
<form method="post" id="task_form" novalidate>
<div>
{% for item in form %}
<div class="col-xs-6">
<div class="form-group">
<label>{{ item.label }}</label>
{{ item }}
</div>
</div>
{% endfor %}
</div>
</form>
<div class="col-xs-12">
<input id="submit" type="submit" value="提 交" class="btn btn-primary center-block" style="width: 100px;">
</div>
</div>
</div>
<h1>任务管理</h1>
<h3>示例1</h3>
<input id="btn1" type="button" value="点击1" class="btn btn-primary">
<h3>示例2</h3>
<input type="text" id="txtuser" placeholder="姓名">
<input type="text" id="txtpwd" placeholder="密码">
<input id="btn2" type="button" value="点击2" class="btn btn-primary">
<form id="from3">
<h3>示例2</h3>
<input type="text" name="user" placeholder="姓名">
<input type="text" name="age" placeholder="年龄">
<input type="text" name="pwd" placeholder="密码">
<input type="text" name="mobile" placeholder="电话">
</form>
<input id="btn3" type="button" value="点击3" class="btn btn-primary">
</div>
{% endblock %}
{% block script %}
<script type="text/javascript">
$(function () {
// 页面框架加载完成之后代码自动执行
bindBtn1Event();
bindBtn2Event();
bindBtn3Event();
bindaddEvent();
})
function bindBtn1Event() {
$("#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);
}
})
})
}
function bindBtn2Event() {
$("#btn2").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
name: $("#txtuser").val(),
password: $("#txtpwd").val()
},
dataType: "JSON",
success: function (res) {
console.log(res);
console.log(res.status);
console.log(res.data);
}
})
})
}
function bindBtn3Event() {
$("#btn3").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: $("#from3").serialize(),
dataType: "JSON",
success: function (res) {
console.log(res);
console.log(res.status);
console.log(res.data);
}
})
})
}
function bindaddEvent() {
$("#submit").click(function () {
$.ajax({
url: '/task/add/',
type: "post",
data: $("#task_form").serialize(),
dataType: "JSON",
success: function (res) {
console.log(res);
console.log(res.status);
console.log(res.data);
}
})
})
}
</script>
{% endblock %}
任务添加(二)
编辑myproject/employee_management/views/task.py
from django import forms
class TaskModelForm(BootStrapModelForm):
class Meta:
model = Task
fields = "__all__"
widgets = {
"detail": forms.TextInput,
}
...
@csrf_exempt
def task_add(request):
print(request.POST)
data_dict = {"status": True}
return HttpResponse(json.dumps(data_dict))
编辑myproject/myproject/urls.py
path('task/add/', task.task_add),
接下来保存数据并进行数据校验
编辑myproject/employee_management/views/task.py
@csrf_exempt
def task_add(request):
print(request.POST)
# 1.用户发送过来的数据进行校验(ModelForm进行数据校验)
form = TaskModelForm(data=request.POST)
if form.is_valid():
form.save()
data_dict = {"status": True}
return HttpResponse(json.dumps(data_dict))
data_dict = {"status": False, "error": form.errors}
return HttpResponse(json.dumps(data_dict))
编辑myproject/employee_management/templates/task_list.html
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">表单</div>
<div class="panel-body">
<form method="post" id="task_form" novalidate>
<div>
{% for item in form %}
<div class="col-xs-6">
<div class="form-group" style="position: relative; margin-top: 20px">
<label>{{ item.label }}</label>
{{ item }}
<span class="error_msg" style="color: red;position: absolute;"></span>
</div>
</div>
{% endfor %}
</div>
</form>
<div class="col-xs-12" style="margin-top: 20px">
<input id="submit" type="submit" value="提 交" class="btn btn-primary center-block" style="width: 100px;">
</div>
</div>
</div>
<h1>任务管理</h1>
<h3>示例1</h3>
<input id="btn1" type="button" value="点击1" class="btn btn-primary">
<h3>示例2</h3>
<input type="text" id="txtuser" placeholder="姓名">
<input type="text" id="txtpwd" placeholder="密码">
<input id="btn2" type="button" value="点击2" class="btn btn-primary">
<form id="from3">
<h3>示例2</h3>
<input type="text" name="user" placeholder="姓名">
<input type="text" name="age" placeholder="年龄">
<input type="text" name="pwd" placeholder="密码">
<input type="text" name="mobile" placeholder="电话">
</form>
<input id="btn3" type="button" value="点击3" class="btn btn-primary">
</div>
{% endblock %}
{% block script %}
<script type="text/javascript">
$(function () {
// 页面框架加载完成之后代码自动执行
bindBtn1Event();
bindBtn2Event();
bindBtn3Event();
bindaddEvent();
})
function bindBtn1Event() {
$("#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);
}
})
})
}
function bindBtn2Event() {
$("#btn2").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
name: $("#txtuser").val(),
password: $("#txtpwd").val()
},
dataType: "JSON",
success: function (res) {
console.log(res);
console.log(res.status);
console.log(res.data);
}
})
})
}
function bindBtn3Event() {
$("#btn3").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: $("#from3").serialize(),
dataType: "JSON",
success: function (res) {
console.log(res);
console.log(res.status);
console.log(res.data);
}
})
})
}
function bindaddEvent() {
$("#submit").click(function () {
// 每次点击,将以前的错误信息清空
$(".error_msg").empty();
$.ajax({
url: '/task/add/',
type: "post",
data: $("#task_form").serialize(),
dataType: "JSON",
success: function (res) {
// 如果数据校验正确
if(res.status){
alert("添加成功");
} else {
// 否则将错误信息显示在输入框下
$.each(res.error, function(name,data){
$("#id_" + name).next().text(data[0]);
})
}
}
})
})
}
</script>
{% endblock %}
在上面的 HTML 代码中,我在操作时很奇怪为什么错误信息会显示在输入框的下面,然后又看了一遍武佩奇老师的视频,发现原理是这样的
ModelForm 在生成页面标签时,会在 input 标签上自动加入required id
,它的值由id_
+ input标签的name属性的值
组成
而在 HTML 中 Javascript 的一行代码,自动在下一行的标签中加入了数据
$("#id_" + name).next().text(data[0]);
明白了吧?
ok
任务列表
在上面 HTML 代码的基础上进行添加,包括:
- 添加数据后列表自动刷新
- 分页
- 搜索
- 实现添加数据后列表自动刷新
编辑myproject/employee_management/templates/task_list.html
location.reload();
- 实现分页与搜索
编辑myproject/employee_management/templates/task_list.html
,在<div class="container">
内加入如下代码
<div>
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">
<span class="glyphicon glyphicon-th-list" aria-hidden="true" style="margin-right: 5px;"></span>
<span>任务列表</span>
</div>
<!-- Table -->
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>标题</th>
<th>级别</th>
<th>负责人</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for obj in queryset %}
<tr>
<th>{{ obj.id }}</th>
<td>{{ obj.title }}</td>
<td>{{ obj.get_level_display }}</td>
<td>{{ obj.user.username }}</td>
<td>
<a class="btn btn-primary btn-xs" href="#">编辑</a>
<a class="btn btn-danger btn-xs" href="#">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<ul class="pagination">
{{ page_string }}
</ul>
<br>
<form method="get">
<div style="display:inline-block; width: 150px;">
<div class="input-group">
<span> <input type="text" class="form-control" placeholder="请输入页码" name="page"></span>
<span class="input-group-btn">
<button class="btn btn-primary" type="submit">跳转</button>
</span>
</div>
</div>
</form>
编辑myproject/employee_management/views/task.py
from employee_management.utils.pagination import Pagination
@csrf_exempt
def task_list(request):
""" 任务列表 """
form = TaskModelForm()
##########################################################
# >>>>>生成页码与搜索
data_dict = {}
search_data = request.GET.get('query', "")
# title__ccontains 表示使用title作为搜索字段进行内容匹配
if search_data:
data_dict["title__contains"] = search_data
# 对搜索内容进行查询,为空表示获取所有数据
queryset = Task.objects.filter(**data_dict).order_by('-id')
page_object = Pagination(request, queryset, page_size=10, page_param="page")
page_queryset = page_object.page_queryset
# 调用对象的html方法,生成页码
page_object.html()
page_string = page_object.page_string
##########################################################
context = {
"queryset": page_queryset,
"form": form,
"page_string": page_string,
"search_data": search_data,
}
return render(request, "task_list.html", context)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/100696.html