浏览器向网站发送请求时,URL 和 表单的形式提交
特点: 页面刷新
Ajax可以实现向后台偷偷发送请求,整个请求和收到回复的过程不需要刷新页面
新建 task_list.html
写错了,应该{% block js
新建 task.py
{% extends 'xlayout.html' %}
{% block mbname %}
<div class="container">
<input type="button" class="btn-primary" id="btn1" value="按钮" onclick="clikem()">input>
div>
{% endblock %}
{% block css %}
<script type="text/javascript">
function clikem() {
$.ajax({
url:'/task/ajax/',
type:'get',
data: {
n1:123,
n2:345
},
success:function(res){
console.log(res);
}
})
}
script>
{% endblock %}
信任请求不需要token验证
装饰器
csrf_exempt可以免除在HTM中写CSRF
.py
.html
绑定事件
根据id选择,有click时,自动执行函数
一般不会返回页面,而是返回json格式,传递过程为字符串
.py
html
这样,我们就学会了如何在浏览器页面不刷新的情况下,如何向后台提交数据
建表
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)
task_list.html
解决显示外联主键的问题
修改models.py中admin表
that’s ok!
{% extends 'xlayout.html' %}
{% load static %}
{% block mbname %}
<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>
{% endblock %}
{% block js %}
<script type="text/javascript">
$(function () {
bindaddEvent();
})
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);
}
})
})
}
{% endblock %}
添加 url task.py 中添加/task/add/'链接和函数
输出传入函数的内容
task.py
只能返回 HttpResponse(json.dumps(data_dict)),不能返回重定向和render 刷新页面
如果成功 data_dict = {“status”: True}
失败 data_dict = {“status”: False, “error”: form.errors}
error中携带了错误信息
# author : Sun; time : 2023/2/10 18:14;
import json
from django import forms
from django.http import JsonResponse
from django.shortcuts import render, redirect, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from bm01.utils.form import BootStrapModelForm
from bm01.models import Task
class TaskModelForm(BootStrapModelForm):
class Meta:
model = Task
fields = "__all__"
widgets = {
"detail": forms.TextInput,
}
@csrf_exempt
def task_add(request):
print(request.POST)
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 JsonResponse(data_dict)
def task_list(request):
form = TaskModelForm()
return render(request, "task_list.html", {"form": form})
task.html
前端优化
使得页面为绝对位置,而错误信息出现以相对的形式,不会撑起来div ,而是相对在每一个输入框下浮
提交按钮不会被向下挤
location.reload();
task.py
def task_list(request):
"""任务列表添加,展示,搜索,同admin_list """
# 添加框
form = TaskModelForm()
# 搜索框
data_dict = {}
search_data = request.GET.get('se', "")
if search_data:
data_dict = {"title__contains": search_data}
queryset = models.Task.objects.filter(**data_dict)
# 分页 页码跳转框
page_obj = Pagination(request, queryset)
context = {
"search_data": search_data,
"form": form,
"queryset": page_obj.page_queryset,
"page_string": page_obj.html()
}
return render(request, "task_list.html", context)
task_list.html
{% extends 'xlayout.html' %}
{% load static %}
{% block mbname %}
<div class="container" style="height: 999px">
<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 style="color:red;position: absolute"></span>
</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;margin-top: 20px">
</div>
</div>
</div>
<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 class="col-xs-4 navbar-right" style="margin-top: -7px">
<form method="get">
<div class="input-group" >
<input class="form-control" name="se" type="text" placeholder="任务名称"
value="{{ search_data }}">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">搜索任务</button>
</span>
</div>
</form>
</div>
</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>
</div>
<div>
<h3>1</h3>
<button class="btn-primary" id="btn1">按钮</button>
<h3>2</h3>
<input type="text" id='u' placeholder="用户名">
<input type="text" id='a' placeholder="年龄">
<button class="btn-primary" id="btn2">按钮</button>
<h3>3</h3>
<form id="form3">
<input type="text" name='uu' placeholder="用户名">
<input type="text" name='aa' placeholder="年龄">
<input type="text" name='bb' placeholder="年龄">
<input type="text" name='ee' placeholder="xx">
<input type="text" name='ff' placeholder="xxx">
<input type="text" name='gg' placeholder="xxx">
<button class="btn-primary" id="btn3">按钮</button>
</form>
</div>
{% endblock %}
{% block js %}
<script type="text/javascript">
$(function () {
bindaddEvent();
bindBtn1Event();
bindBtn2Event();
bindBtn3Event();
})
function bindaddEvent() {
$("#submit").click(function () {
$.ajax({
url: '/task/add/',
type: "post",
data: $("#task_form").serialize(),
dataType: "JSON",
success: function (res) {
if (res.status) {
alert("添加成功!!!");
location.reload();
} else {
$.each(res.error, function (name, data) {
$("#id_" + name).next().text(data[0]);
})
}
}
})
})
}
function bindBtn1Event() {
$('#btn1').click(function () {
$.ajax({
url: '/task/ajax/',
type: 'post',
data: {
n1: 123,
n2: 345
},
{#拿到字符串自动转化为前端对象#}
dataType: "JSON",
success: function (res) {
console.log(res);
console.log(res.a);
console.log(res.b);
console.log(res.c);
}
})
})
}
function bindBtn2Event() {
$('#btn2').click(function () {
$.ajax({
url: '/task/ajax/',
type: 'post',
data: {
user: $("#u").val(),
age: $("#a").val(),
},
{#拿到字符串自动转化为前端对象#}
dataType: "JSON",
success: function (res) {
console.log(res);
}
})
})
}
function bindBtn3Event() {
$('#btn3').click(function () {
$.ajax({
url: '/task/ajax/',
type: 'post',
data: $("#form3").serialize(),
{#拿到字符串自动转化为前端对象#}
dataType: "JSON",
success: function (res) {
console.log(res);
}
})
})
}
</script>
{% endblock %}