カスタムページネーション
1. 目的と環境設定
目的は、ページネーションをモジュールとして作成し、必要な場所で直接呼び出すことです。
環境設定: Djangoアプリの生成と設定
URL設定
<pre><code>from django.urls import path
from django.contrib import admin
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('user_list/', views.user_list_view),
]
</code></pre>
アプリ登録
<pre><code>INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp',
]
</code></pre>
モデル設定
<pre><code>from django.db import models
class UserInfo(models.Model):
user_name = models.CharField(max_length=32)
age = models.IntegerField()
</code></pre>
2. 分析
大規模なウェブサイトではページネーションが一般的に使用されます。すべてのコンテンツを一度に表示する代わりに、ユーザーはページごとに必要なデータだけを見ることができます。
3. ページネーションコードの構築
3.1 データの生成
<pre><code>from django.shortcuts import render, HttpResponse
from myapp import models
def user_list_view(request):
for i in range(500):
data = {'user_name': f'user_{i}', 'age': i}
models.UserInfo.objects.create(**data)
return HttpResponse('データ作成完了')
</code></pre>
3.2 HTMLでのデータ表示
<pre><code><html lang="en">
<head>
<meta charset="UTF-8">
<title>ユーザーリスト</title>
</head>
<body>
<table>
{% for entry in user_data %}
<tr>
<td>{{ entry.user_name }}</td>
<td>{{ entry.age }}</td>
</tr>
{% endfor %}
</table>
<div>
{{ page_navigation|safe }}
</div>
</body>
</html>
</code></pre>
ビュー関数:
<pre><code>def user_list_view(request):
users = models.UserInfo.objects.all()
return render(request, 'user_list.html', {'user_data': users})
</code></pre>
3.3 指定行数の取得
<pre><code>def user_list_view(request):
current_page = request.GET.get('page', 1)
current_page = int(current_page)
start_index = (current_page - 1) * 10
end_index = current_page * 10
users = models.UserInfo.objects.all()[start_index:end_index]
return render(request, 'user_list.html', {'user_data': users})
</code></pre>
セキュリティとXSS対策
ページリンクをHTMLとして安全に扱うには、テンプレートエンジンの mark_safe を利用します。
<pre><code>from django.utils.safestring import mark_safe
# ページリンク生成部分
page_links = []
if current_page > 1:
prev_link = f'<a href="{base_url}?page={current_page - 1}">前へ</a>'
page_links.append(prev_link)
# ...以下略...
return mark_safe("".join(page_links))
</code></pre>