day08ジャンゴ:contentTypeのファイルアップロードページャ
A .Django:settings.py
APPEND_SLASH =真:「スラッシュ」を使用すると、ブラウザのリクエストURLを見つけた場合ジャンゴ、そして薄いエンド内部I urls.pyパス:「スラッシュ」を追加し、ブラウザが「斜め追加してみましょう、ブラウザにリダイレクトを与えますバー「もう一度アクセス
APPEND_SLASH = Flase: "スラッシュ" なし
注:要求を取得しますが、要求はこのポストを行うことができないだけのために
二.Django:AJAXを作るために削除ライブラリ管理システム
<身体>
<!DOCTYPE HTML>
{%csrf_token%}
<H1>ブックを表示するには!</ H1>
<のdivクラス= "コンテナ">
<DIVクラス= "行">
<DIV CLASS = "COL-MD-8 COL-MD-オフセット-2">
<a href="{% URL'booksadd' %}" class="btn btn-primary btn-sm">添加书籍する</a>
<テーブルクラス=「テーブルのテーブルストライプテーブルホバーテーブルボーダー」>
<THEAD>
<TR>
<TH> ID </目>
<TH>ブック名</目>
<TH>価格</目>
<TH>出版日</目>
<TH>を押し</目>
<TH>操作</目>
</ TR>
</ THEAD>
<TBODY>
{book_list%で書籍の%}
<TR>
<TD> {{forloop.counter}} </ TD>
<TD> {{book.title}} </ TD>
<TD> {{book.price}} </ TD>
<TD> {{book.pub_date |日付: "はYmd"}} </ TD>
<TD> {{book.publish}} </ TD>
<TD>
<ボタンNID = "{{book.nid}}" クラス= "BTN-危険BTN-SM delbtn BTN">删除</ボタン>
<a href="{% URL'booksedit' book.nid %}" class="btn btn-warning btn-sm">编辑する</a>
{#<a href="{% URL'booksdelete' book.nid %}" class="btn btn-danger btn-sm">删除する</a>#}
</ TD>
</ TR>
{%ENDFOR%}
</ TBODY>
</ TABLE>
</ div>
</ div>
</ div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
<script>
$('.delbtn').click(function () {
var nid = $(this).attr('nid');
var tr = $(this).parent().parent();
$.ajax({
url: `/books/ajaxdelete/${nid}`,
type: 'post',
data: {
csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val(),
},
success: function (response) {
var rsp = JSON.parse(response)
if (rsp.state) {
tr.remove()
}
},
})
})
</script>
</body>
三.Django: contentType
1.发送contentType: urlencoded这种数据格式的数据, 直接发
request.POST
request.GET
request.body
user=bajie&pwd=123&a=6 #这种数据封装格式叫做: urlencoded
contentType: #浏览器告诉服务器: 请求体的数据封装格式
contentType: urlencoded #form表单和ajax默认都是是这个类型
2.发送contentType: 'json'数据格式
2.1.发送端:ajax
Django的post需要验证的token先关掉
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
{% csrf_token %}
<script>
$('.cal').click(function () {
num1 = $('#num1').val();
num2 = $('#num2').val();
$.ajax({
url: `/handle_ajax/`,
type: 'post',
contentType: 'json',
data: JSON.stringify({
num1:num1,
num2:num2,
}),
success: function (response) {
$('#num3').val(response);
}
})
})
</script>
2.2.接收端
Django 只帮我们处理 contentType = "urlencoded"类型的数据, 交给request, 其他数据类型返回空字典
json格式的请求体: 在request.body里(b'{"num1":"1","num2":"2"}'): 需要我们自己处理
def handle_ajax(request):
rsp = json.loads(request.body.decode('utf8'))
num1 = rsp.get('num1')
num2 = rsp.get('num2')
return HttpResponse(str(int(num1)+int(num2)))
四.Django: 文件上传
1.form表单的文件上传
发送enctype="multipart/form-data"数据格式
formdata格式的请求体: 在request.FILES里(<MultiValueDict: {'file_obj': [<InMemoryUploadedFile: 激活码.txt (text/plain)>]}>); 需要我们自己处理
1.1.发送端
enctype="multipart/form-data": 必须要写, 不然会按urlencoded, 请求体会取到一个文件名而已
<form action="/fileput/" method="post" enctype="multipart/form-data">
用户名<input type="text" name="user">
文件<input type="file" name="file_obj">
<input type="submit">
</form>
1.2.接收端
request.FILES: 文件使用这个来接收到
request.FILES.get('file_obj'): 取文件对象
def fileput(request):
import os
from s15ajax import settings
file_obj = request.FILES.get('file_obj')
path = os.path.join(settings.BASE_DIR, file_obj.name)
with open(file_obj.name, 'wb') as f:
for line in file_obj:
f.write(line)
return HttpResponse('ok')
2.ajax的文件上传
发送隐含的enctype="multipart/form-data"原form-data数据格式
2.1.发送端
使用js自带的构造函数FormData创建formdata对象
然后把input里面找到的文件对象,追加到formdata对象里
ajax里面发送原生的data:formdata 数据格式
<body>
<form>
用户名 <input type="text" id="user">
文件<input type="file" id="file_obj">
<input type="button" class="filebtn" value="提交">
</form>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
{% csrf_token %}
<script>
$('.filebtn').click(function () {
var user = $('#user').val();
var file_obj = $('#file_obj')[0].files[0]; //获取文件对象
var formdata = new FormData();
formdata.append("file_obj", file_obj);
formdata.append("user", user);
$.ajax({
url:`/fileput/`,
type:'post',
processData: false, //不处理数据
contentType: false, //不设置内容类型 使用原formdata数据
data: formdata,
success: function (response) {
console.log(response)
}
})
});
</script>
</body>
2.2.接收端
不变: 和form表单文件上传的接收端一样
五.Django: 分页器
1.数据库批量插入数据
方式一: for循环: 每次都一个insert,效率低
def index(request):
for i in range(100):
Book.objects.create(name='book_%s' % i, price=i*i)
方式二: 使用bulk_create()方法批量插入, 一个inset,100条value(),效率高
def index(request):
book_list = []
for i in range(100):
book = Book(name='book_%s' % i, price=i*i)
book_list.append(book)
Book.objects.bulk_create(book_list)
2.分页器的使用
from django.core.paginator import Paginator
book_list = Book.objects.all() #去数据库取记录
paginator = Paginator(book_list, 10) #先实例化
paginator.count #数据总数 100
paginator.num_pages #总页数 10
paginator.page_range #页码的列表 range(1, 11)
page = paginator.page(5) #第5页的对象, 可遍历
for i in page: #可遍历
print(i)
page.has_next() #True或False: 判断是否有上一页
page.has_previous() #True或False: 判断是否有下一页
page.next_page_number() #下页的页号
page.previous_page_number() #上页的页号
3.分页实例
3.1.views.py
from django.shortcuts import render, HttpResponse
from django.core.paginator import Paginator, EmptyPage
from app01.models import Book
def index(request):
book_list = Book.objects.all()
paginator = Paginator(book_list, 10)
try:
current_page_number = request.GET.get('page', 1)
current_page_number = int(current_page_number)
current_page = paginator.page(current_page_number)
except EmptyPage as e:
current_page_number = 1
current_page = paginator.page(1)
return render(request, 'index.html', locals())
3.2.index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap 101 Template</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<ul>
{% for book in current_page %}
<li>{{ book.name }} ---- {{ book.price }}</li>
{% endfor %}
</ul>
<nav aria-label="Page navigation">
<ul class="pagination">
{% if current_page.has_previous %}
<li>
<a href="?page={{ current_page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% endif %}
{% for page_num in paginator.page_range %}
{% if page_num == current_page_number %}
<li class="active"><a href="/index/?page={{ page_num }}">{{ page_num }}</a></li>
{% else %}
<li><a href="/index/?page={{ page_num }}">{{ page_num }}</a></li>
{% endif %}
{% endfor %}
{% if current_page.has_next %}
<li>
<a href="?page={{ current_page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% endif %}
</ul>
</nav>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
</body>
</html>