モデルサプリメントフィールド
(多い)パラメータの選択/フィールド
性別、ユーザー教育、作業状況、婚姻状況(限られた範囲内で設定し、利用可能なことができます)
app01 / models.py
from django.db import models
# Create your models here.
class User(models.Model):
username = models.CharField(max_length=32)
age = models.IntegerField()
choices = (
(1, '男'), (2, '女'), (3, '其他')
)
gender = models.IntegerField(choices=choices)
"""
1 存choice里面罗列的数字与中文对应关系
print(user_obj.get_gender_display())
只要是choices字段 在获取数字对应的注释 固定语法
get_choices字段名_display()
2 存没有罗列迟来的数字
不会报错 还是展示数字
"""
class Book(models.Model):
title = models.CharField(max_length=32)
データベースに同期され、いくつかのテストデータを追加
テストテストファイル
限り選択フィールドとして、取得したデジタルノートに対応し、固定構文:
get_choices字段名_display()
、文句やデジタルは表示されません、番号のないリストを保っていません
バリュー特長
私たちは、対応関係との間の対応が出ています
何の対応関係が存在しない場合は、それを直接元の値にアウト
一般的な例 CRMで
MVCモデルとMTVの科学
主張ジャンゴMTVのフレームは、(実際には、MVCの本質です)
M:モデル
T:テンプレート
V:ビュー
MVC
- M:モデル
- V:ビュー
- C:コントローラコントローラ(URLの)
アヤックス
AJAX(非同期JavaScriptとXML非同期JavascriptとXML)
特長:非同期提出、パーシャルリフレッシュ
たとえば:インスタントチェック登録ユーザーは、ユーザー名はgithubの中に存在する場合
いくつかの一般的な方法のGET、POSTリクエストを送信します
a 标签的 href 属性 GET请求
直接在浏览器窗口输入 url 敲回车 GET请求
form 表单提交 GET/POST
ajax 提交 GET/POST
以下の要求は、主にAJAXを介して送信されます
JavaScriptであるが、JavaScriptネイティブの操作がより複雑にこの技術をAJAX、我々は直接jQueryのAJAXを使用するように、利便性のためにここにいます
最大の利点のAjax:ページ全体をリロードせずに、ページのコンテンツのサーバと更新パーツとデータを交換することができます。(この機能は、ユーザ要求と無意識のうち対応する処理が完了したことに感じです)
Ajaxでの小さなケースを作ります
そこ3つの入力ボックスには、最初の2つのデジタル入力の入力ボックスには、ページを更新せずに、送信ボタンAJAXリクエストページをクリックして、で、自動的に3番目のボックスに2の数を記入します
ここでは、jQueryのAJAXあり、jQueryのを含めることを忘れないでください
準備
- 新しいプロジェクトを作成し、基本的な設定を完了するために、
- ミドルウェアに一時的に要求するので、設定を投稿する使用はCSRFをコメントしているので
- ユーザーのブラウザの入力に一致するようにURLアドレスを書きます
- ページにレンダリングブラウザにページを達成するための機能を表示して、ページがユーザーの入力ボックスの内容に戻ります。
day57 / settings.py
"""
Django settings for day57 project.
Generated by 'django-admin startproject' using Django 1.11.11.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'p0d7eiqh64wgd#!!rso@!wv#4w(%-)6%hb6q^4ci=+h54h@syx'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config', # 1.检查 APP 是否已注册
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware', # 2.检查 csrf中间件 是否已注释掉
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'day57.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
, # 3.检查 templates 文件夹是否已注册
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'day57.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', # 4.检查 数据库配置信息(本文打算采用 django 自带的 sqlite3 进行测试,就不额外配置数据库了(__init__.py 文件里也就不配了))
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
LOGGING = { # 5.添加数据库操作语句打印(一有数据库操作就会在 pycharm 控制台打印对应的 SQL 语句)
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [ # 6.配置静态资源路径(方便使用静态资源路径动态解析)
os.path.join(BASE_DIR, 'static')
]
プロジェクトのルートディレクトリにブートストラップは、静的なフォルダを作成します
設定URL、紙、ルート分布(まあたくさんの練習)
day57 / urls.py
"""day57 URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url, include # 下面用到了 include ,要自己导入这个模块
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^user/', include('app01.urls')), # 写成字符串就会根据配置信息自动去查找,就不需要自己导模块过来了
]
app01 / urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^index/', views.index, name='user_index'), # 匹配路由并取别名,方便后期反向解析 url
]
app01 / views.py
from django.shortcuts import render
# Create your views here.
def index(request):
return render(request, 'index.html') # 用户访问 http://127.0.0.1:8000/user/index/ 直接给他返回 index.html 这个页面
テンプレート/ index.htmlを
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试页</title>
{# 为了测试方便,这里就用网上的 jquery 了,用 CDN 的形式引入#}
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
{# 下面练习一下静态资源路径动态解析,并且 boostrap 放在本地会有语法提示,可以加快开发效率#}
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
</head>
<body>
{#随便搭一个页面#}
<div class="container">
<div class="row">
<div class="text-center">
<input type="text"> +
<input type="text"> =
<input type="text">
<button class="btn btn-primary">计算</button>
</div>
</div>
</div>
</body>
</html>
ブラウザは、基本的な作業の準備ができてアクセスするかどうかをテスト(成功しました)
手は、Ajaxを使用して結果を達成します
アイデア解析
私たちは、結果ボックスに記入し、要求を取得し、フロントエンドにデータを返すために、データのフロントエンドを計算]ボタンをクリックすると、AJAXのバックエンドにバックエンドをリクエストを送信し、その後、情報を入力しています
図から分かるように、私たちのブレークスルーは、ボタンのクリックイベントを計算することです
app01 / urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^index/', views.index, name='user_index'),
url(r'^compute/', views.compute, name='user_compute'), # 用来处理用户的计算请求
]
app01 / views.py
from django.shortcuts import render, HttpResponse
# Create your views here.
def index(request):
return render(request, 'index.html') # 用户访问 http://127.0.0.1:8000/user/index/ 直接给他返回 index.html 这个页面
from django.http import JsonResponse # 下面发json数据要用到
def compute(request):
# 判读是否是 ajax 请求
if request.is_ajax():
# 定义一个空的字典,用来存放一会儿的返回信息
back_dic = {
}
# 前端 ajax采用的是 post 请求,所以这里这样获取数据
num1 = request.POST.get('num1')
num2 = request.POST.get('num2')
# 判断数据格式是否正确
if num1.isdigit() and num2.isdigit():
try:
res = int(num1) + int(num2)
back_dic['status'] = 200
back_dic['res'] = res
except Exception as e:
print(e)
back_dic['status'] = 100
back_dic['err'] = e
# 格式不正确返回错误信息
else:
back_dic['status'] = 100
back_dic['err'] = '请输入合法数字!'
# 用 JsonResponse 将字典打包成 json 格式数据返回给前端
# json 格式的数据前端可以直接解析成 前端的自定义对象
return JsonResponse(back_dic)
テンプレート/ index.htmlを
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试页</title>
{# 为了测试方便,这里就用网上的 jquery 了,用 CDN 的形式引入#}
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
{# 下面练习一下静态资源路径动态解析,并且 boostrap 放在本地会有语法提示,可以加快开发效率#}
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
</head>
<body>
{#随便搭一个页面#}
<div class="container">
<div class="row">
<div class="text-center">
<input type="text" id="num1"> +
<input type="text" id="num2"> =
<input type="text" id="res">
<button class="btn btn-primary" id="button1">计算</button>
</div>
</div>
</div>
<script>
{# 1.为了能够获取到对应输入框和按钮以及输入框的值,我们需要先给他们加上 id #}
$('#button1').click(function (e) { {# 2.给我们的 计算 按钮绑定点击事件,点击时用 ajax 发送请求,然后后端计算并返回数值,放在 id 为 res 的 input 里 #}
$.ajax({ {# 3.Jquery 的 ajax,需要下面几个参数,记得写上(Ajax 的括号内是一个大括号,然后再写的参数) #}
url: '{% url "user_compute" %}', {# 4.写 ajax 发送请求的地址,这里用的 url 反向解析 #}
type: 'post', {# 5.采用 post 请求发送数据 #}
data: { {# 6.把要发送过去的数据打包 #}
'num1': $('#num1').val(), {# 7.获取到 id 为 num1 的标签的 value值 #}
'num2': $('#num2').val()
},
success: function (data) { {# 8.请求成功的回调函数 #}
if (data.status == 200) { {# 9.后端手动设置的码, 200 表示数据类型没问题 #}
$('#res').val(data.res); {# 数据没问题就打印出来 #}
} else { {# 10.码不是 200 表示数据类型有误等,弹窗提示错误信息 #}
alert(data.err);
}
}
})
})
</script>
</body>
</html>
リクエストページビューの結果
request.is_ajax()
現在のリクエストがAjaxのリクエストであるかどうかを決定する方法(GETまたはPOSTのどちらか、限りAjaxは提出して、識別することができます)郵送で提出したAJAX要求、名前のないタグは、それは問題ではない属性、我々はすでに、キーと値のペア(フォームの形で主要な役割名)を指定しました
送信データの符号化形式のフロントエンドをCONTENTTYPE
エンコード形式フロント送信データの後端部(共通)
application/x-www-form-urlencoded
- フォームフォームのデフォルトのエンコード形式
- データ形式:名=ジェイソン&PWD = 123
- Djangoのバックエンドは自動的にデータ用URLエンコードエンコード形式を解析し、(彼は、ファイル名を得たときに、ファイル転送)を取得するためにユーザーのためrequest.POSTを置きます
- フォームフォームのデフォルトのエンコード形式
multipart/form-data
- Djangoのバックエンドは自動的に限り、あなたはエンコーディングを指定するようFORMDATAが自動的に解析していると、ユーザーが取得するためにrequest.FILESに入れ、URLエンコードエンコード形式と一致している限りのデータを解析し、request.POSTを配置します
- JSON
概要:データの伝送の前後端は、それ以外の場合は、データを取ることはありません、あなたのデータ形式とエンコード形式ではなく無謀に、同じであることを確認してください
Ajaxのデータを提出
Ajaxのデフォルトのデータの提出は、URLエンコードされました
発生しません。この問題に関する前後端コーディングとデータ形式契約上のフォーマットに準拠していません。
データ形式は、Ajax、JSONを送りました
DjangoはバックエンドのJSONデータのフォーマット、および自動的にrequest.POSTまたは内部request.FILESに解析しません、それはJSON形式のデータを解析しませんが、それはrequest.bodyに無傷でした
$('#b1').on('click',function () {
// 点击按钮 朝后端发送post请求
$.ajax({
url: '', // 控制发送给谁 不写就是朝当前地址提交
type: 'post', // 发送方式是post请求
data: JSON.stringify({'username': 'jason', 'password': 123}), // 发送的数据
contentType: 'application/json', // 告诉后端你这次的数据是json格式
success: function (data) { // data形参用来接收异步提交的结果
// 将后端计算好的结果 通过DOM操作 渲染到第三个input矿中
$('#i3').val(data)
}
})
})
バックエンドは独自の処理を、手動でJSON形式のデータ収集にrequest.bodyする必要があります
from django.shortcuts import render,HttpResponse
from app01 import models
# Create your views here.
def index(request):
# 验证前后端传输数据的编码格式
if request.method == 'POST':
print(request.body)
# 后端 需要手动去request.body中获取json格式数据 自己处理
json_str = request.body
import json
s = json_str.decode('utf-8')
ral_d = json.loads(s)
print(ral_d, type(ral_d))
return HttpResponse('OK')
return render(request, 'index.html')
Ajaxの転送ファイル
保存されたファイルオブジェクトファイルのタグを取得する方法は?
- 最初のinputタグに格納されたファイルへのjQueryを使用して検索します
- ターゲットネイティブJSにjQueryオブジェクト
- ネイティブ・オブジェクトのメソッド.filesを使用してJS [0]得られたファイルオブジェクトはラベルの内側に格納されています
- 二つのパラメータ(PROCESSDATA、contentTypeの)偽であるを必ず指定してください
// ajax传输文件
$('#b1').on('click',function () {
// ajax 传输文件 建议使用内置对象 formdata
var formData = new FormData(); // 既可以传普通的键值对 也可以传文件
// 添加普通键值(后续可以改成 for 循环填充)
formData.append('username','jason');
formData.append('password','123');
formData.append('my_file',$('#d1')[0].files[0]);
$.ajax({
url:'', // 控制发送给谁 不写就是朝当前地址提交
type:'post', // 发送方式是post请求
data:formData, // 发送的数据
// ajax发送文件需要指定两个额外的参数
processData:false, // 告诉前端不要处理数据
contentType:false, // 不适用任何编码 因为formdata对象自身自带编码 django后端也能够识别formdata对象
success:function (data) { // data形参用来接收异步提交的结果
{# alert(data) #}
// 将后端计算好的结果 通过DOM操作 渲染到第三个input矿中
$('#i3').val(data)
}
})
})
シリアル化アセンブリ
知識の分離が終了する前と後
別個のアナログ・フロント・エンド、大辞典JSONの伝送フォーマットにフロントエンド
from django.core import serializers # django自带的一个小型的序列化工具
from app01 import models
import json
def reg(request):
user_list = models.User.objects.all()
# 将所有的数据都组织成一个符合 json 格式的一个个的字典
# user_l = []
# for user_obj in user_list:
# user_l.append(
# json.dumps({
# 'username': user_obj.username,
# 'age': user_obj.age,
# 'gender': user_obj.get_gender_display()
# })
# )
res = serializers.serialize('json', user_list) # 指定序列化格式为 json
return render(request, 'index.html', locals())
JSON形式のデータは、前項から受信しました
[{
"model": "app01.user",
"pk": 1,
"fields": {
"username": "jason",
"age": 18,
"gender": 1
}
}, {
"model": "app01.user",
"pk": 2,
"fields": {
"username": "tank",
"age": 24,
"gender": 3
}
}, {
"model": "app01.user",
"pk": 3,
"fields": {
"username": "egon",
"age": 73,
"gender": 2
}
}, {
"model": "app01.user",
"pk": 7,
"fields": {
"username": "kevin",
"age": 29,
"gender": 4
}
}]
フォーマットは行にすべてを混沌とした場合は、解決に役立つツールを見つけることができますどのようなウェブサイト(オンラインチェックJSON形式)
現在、小さな直列化モジュールシリアライザ
rest_frameworkは、良くあります。。。その後伴うだろう
from app01 import models
from django.core import serializers # django 自带的一个小型的序列化工具
def reg(request):
user_list = models.User.objects.all()
res = serializers.serialize('json', user_list)
return render(request, 'index.html', locals())
ページ(ポップ)を構築するために使用するSweetalert
- 静的リソースファイルを設定することを確認しますsettings.py
- sweetalertオーバーの下では、静的下に置きます
- ページに対応組み込まダイナミック解像度:JQ、ブートストラップ(CSS / JS)、sweetalert(CSS / JS)(私たちが使用するには、ブートストラップによって異なります)
以下のボタンが書かれていますが、また、などのIDをバインドしていません
中国のサポートは非常に良いではありませんポップ、手動でスタイルを変更します
(これは他の場所には影響しません)スタイルを調整し、Googleのブラウザは階層を参照して、手書きのスタイルを上書きします
<style>
div.sweet-alert h2{
padding-top: 10px;
}
</style>
公式サイトsweetalertスクリプトに、ボタンへの結合事象は、それがトリガー、来るのスタイルを見つけるために
テキストをキャンセル変更cancelButtonText(自分自身を追加しました)
カスタムプロパティを追加するには、ボタン、結合のuser_idは、ポップは過去のuser_idヘアAJAXを取得する場所を削除書き込みAJAXを確認します
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'dist/sweetalert.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
<script src="{% static 'dist/sweetalert.min.js' %}"></script>
<style>
div.sweet-alert h2{
padding-top: 10px;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h2 class="text-center">数据展示</h2>
<table class="table-striped table table-hover table-bordered">
<thead>
<tr>
<th>序号</th>
<th>主键</th>
<th>用户名</th>
<th>年龄</th>
<th>性别</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for user in user_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ user.pk }}</td>
<td>{{ user.username }}</td>
<td>{{ user.age }}</td>
<td>{{ user.get_gender_display }}</td>
<td>
<button class="btn btn-primary btn-sm">编辑</button>
<button class="btn btn-danger btn-sm del" user_id="{{ user.pk }}">删除</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<script>
$('.del').click(function () {
// 获取当前标签对象
var $btnEle = $(this);
swal({
title: "你确定要删吗?",
text: "你要是删了,你就准备跑路吧!",
type: "warning",
showCancelButton: true,
confirmButtonClass: "btn-danger",
confirmButtonText: "是的,老子就要删!",
cancelButtonText: "算了,算了!",
closeOnConfirm: false,
showLoaderOnConfirm: true
},
function(){
// 朝后端发送ajax请求
$.ajax({
url:'',
type:'post',
data:{'delete_id':$btnEle.attr('user_id')},
success:function (data) { // 后端发字典过来 前端不需要你手动转 会自动帮你转换成js自定义对象
if (data.code == 100){
{#window.location.href = ''; // 不写就是条到当前页面#}
// 通过DOM操作 实时改变页面
// 将被点击的删除按钮所在的那一行直接从DOM树中删掉
$btnEle.parent().parent().remove();
swal("删掉了!", "赶紧回去收拾行李吧,准备跑路!", "success");
}else{
swal('发生了未知的错误','估计是有bug了','info')
}
}
});
});
})
</script>
</body>
</html>
伝送jsonResponse辞書の後端部、及びフロントエンドは自動的にカスタムオブジェクトに解決し得ることができ、その属性が直接ドット構文で動作することができます
from django.http import JsonResponse
import time
def userlist(request):
if request.is_ajax():
time.sleep(3)
"""
一般情况下 针对ajax请求 后端通常都是返回一个字典
"""
back_dic = {'code':100,'msg':''}
# 直接获取用户想删除的数据的id值
delete_id = request.POST.get('delete_id')
# 直接利用queryset方法 批量删除
models.User.objects.filter(pk=delete_id).delete()
# 要给前端ajax返回一个消息(字典)
back_dic['msg'] = '真的删除了!'
return JsonResponse(back_dic)
user_list = models.User.objects.all()
return render(request,'userlist.html',locals())
ページのデータは更新問題ではありません
リフレッシュは怠惰に最も直接的な方法です
この方法は非常に良いではありません(ポップ・アニメーションの第二段落が行われ、それがページを更新していません)
行全体を削除します。
親タグ(フルライン)を取得し、その後、DOM操作によってDOMツリーからそれを削除 $btnEle.parent().parent().remove()
( - > 1,3,4,5)号、焦点はここにいない継続的な最初の問題ではありません
カスタムページャ
一括挿入テストデータbulk_create
挿入及び効果はなく、少し速く(以上分に挿入部1000、第2のプラグのバッチ)
l = []
for i in range(10000):
l.append(models.Book(title=f'书籍{i}'))
models.Book.objects.bulk_create() # 批量插入数据
ページング
いくつかの重要なパラメータがありますどのように多くのページあたり、ページを開始し、小節番号を開始し、最後の数
彼らの関係の法律を導き出します
"""
per_page_num = 10
current_page start_page end_page
1 0 10
2 10 20
3 20 30
4 30 40
per_page_num = 5
current_page start_page end_page
1 0 5
2 5 10
3 10 15
4 15 20
start_page = (current_page - 1) * per_page_num
end_page = current_page* per_page_num
10000
10
1000
10001
10
1001
"""
組み込み関数のdivmod(101、10)を使用することができます - 10 1>はページ数を算出し、
htmlタグをレンダリングする循環背面に(遠位ないを行います)
ページのエッジ決意
実現ページャの最終版を使います
一般第三者の一般的なファイルは、その後にPythonコード内で、新しいutilsのフォルダを作成します。
バックエンド
オーバーインポートし、それらの中にフォルダやファイル、ページングコードの作成、使用
app01 / utilsの/ mypage.py書かれたページングクラス、直接十分な使用
class Pagination(object):
def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
"""
封装分页相关数据
:param current_page: 当前页
:param all_count: 数据库中的数据总条数
:param per_page_num: 每页显示的数据条数
:param pager_count: 最多显示的页码个数
用法:
queryset = model.objects.all()
page_obj = Pagination(current_page,all_count)
page_data = queryset[page_obj.start:page_obj.end]
获取数据用page_data而不再使用原始的queryset
获取前端分页样式用page_obj.page_html
"""
try:
current_page = int(current_page)
except Exception as e:
current_page = 1
if current_page < 1:
current_page = 1
self.current_page = current_page
self.all_count = all_count
self.per_page_num = per_page_num
# 总页码
all_pager, tmp = divmod(all_count, per_page_num)
if tmp:
all_pager += 1
self.all_pager = all_pager
self.pager_count = pager_count
self.pager_count_half = int((pager_count - 1) / 2)
@property
def start(self):
return (self.current_page - 1) * self.per_page_num
@property
def end(self):
return self.current_page * self.per_page_num
def page_html(self):
# 如果总页码 < 11个:
if self.all_pager <= self.pager_count:
pager_start = 1
pager_end = self.all_pager + 1
# 总页码 > 11
else:
# 当前页如果<=页面上最多显示11/2个页码
if self.current_page <= self.pager_count_half:
pager_start = 1
pager_end = self.pager_count + 1
# 当前页大于5
else:
# 页码翻到最后
if (self.current_page + self.pager_count_half) > self.all_pager:
pager_end = self.all_pager + 1
pager_start = self.all_pager - self.pager_count + 1
else:
pager_start = self.current_page - self.pager_count_half
pager_end = self.current_page + self.pager_count_half + 1
page_html_list = []
# 添加前面的nav和ul标签
page_html_list.append('''
<nav aria-label='Page navigation>'
<ul class='pagination'>
''')
first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
page_html_list.append(first_page)
if self.current_page <= 1:
prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
else:
prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)
page_html_list.append(prev_page)
for i in range(pager_start, pager_end):
if i == self.current_page:
temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
else:
temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
page_html_list.append(temp)
if self.current_page >= self.all_pager:
next_page = '<li class="disabled"><a href="#">下一页</a></li>'
else:
next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
page_html_list.append(next_page)
last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
page_html_list.append(last_page)
# 尾部添加标签
page_html_list.append('''
</nav>
</ul>
''')
return ''.join(page_html_list)
ではapp01 / views.py使用
# ...其他代码
from app01.utils.mypage import Pagination
def book(request):
# 使用封装好的自定义分页器
book_list = models.Book.objects.all()
current_page = request.GET.get("page", 1)
all_count = book_list.count()
page_obj = Pagination(current_page=current_page, all_count=all_count, per_page_num=10)
page_queryset = book_list[page_obj.start:page_obj.end]
return render(request, 'booklist.html', locals())
# ...其他代码
テンプレート/ booklist.htmlページ
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'dist/sweetalert.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
<script src="{% static 'dist/sweetalert.min.js' %}"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
{% for book in page_queryset %}
<p>{{ book.title }}</p>
{% endfor %}
{{ page_obj.page_html|safe }} {# 支持转义,让 html 格式的字符串可以渲染出来 #}
</div>
</div>
</div>
</body>
</html>