このページでは Django を利用した「足あと」機能の実現方法について解説していきます。
「足あと」機能が搭載された代表的なサービスとしては mixi が挙げられると思います(今は廃止されたようですが…)。
足あと機能とは、ユーザーが他のユーザーのページを閲覧した際に、その閲覧履歴を記録する機能になります。要は、誰が誰のページを閲覧したのかの情報を足あととして記録していく機能です。

この足あとは記録されるだけでなく、ユーザー自身のマイページから確認することも可能です。
このような機能によって、ユーザーは自身の情報や日記等を閲覧した人物を知ることができるようになり、また誰から興味を持たれているかを知ることもできるようになります。

賛否両論のある機能ではあるのですが、実際に足あと機能を搭載したウェブアプリを開発してみることで Django についての理解を深めることができると思いますので、このページで足あと機能の実現方法について解説していきたいと思います。
また、足あとの情報を表示しないとしても、閲覧履歴として情報を管理しておくことでユーザーの興味をアプリ側で把握することもできます。そして、その興味に合わせてオススメユーザーを紹介することもできますし、ショッピングアプリなどであればオススメ商品などを紹介することもできると思います。
使い道は結構あると思いますので、是非ページを読み進めていただければと思います!
Contents
足あと機能の実現方法
では、足あと機能の実現方法について解説していきます。
足あと用のモデルを作成する
前述の通り、足あと機能とは、簡単に言えば、誰が誰のページを閲覧したかを管理し、さらにその情報を表示する機能となります。

このような機能を実現するために、誰が誰のページを閲覧したかを管理するためのモデルを定義します。いつ閲覧したかも管理したいので、閲覧した日時も管理できるようにしたいと思います。
モデルの定義例は下記のようになります。src が「誰が閲覧したのか」、dst が「誰のページを閲覧したのか」を管理するフィールドであり、さらに date が閲覧した日時を管理するフィールドとなります。
class FootPrint(models.Model):
src = models.ForeignKey(User, on_delete=models.CASCADE, related_name='src_footprint')
dst = models.ForeignKey(User, on_delete=models.CASCADE, related_name='dst_footprint')
date = models.DateTimeField(default=timezone.now)
また、上記における User は Django に標準で用意されているユーザー管理モデルとなります。ユーザーの区別が付けられるよう、足あと機能を実現するためにはユーザーのログイン機能も必要となります。
このユーザーのログイン機能については下記ページで解説しています。
後述の 足あと機能付きの簡単なウェブアプリのサンプル では、足あと機能付きの簡単なウェブアプリとしてログイン機能も含めたソースコードの紹介も行います。が、ログインに関する解説は省略させていただいていますので、分からない点などあれば上記ページをご参照いただければと思います。
スポンサーリンク
足あとの情報を管理する
そして、このモデルのオブジェクトによって、誰(src)が誰(dst)のページをいつ(date)閲覧したかの情報を1つ1つ記録していきます。
具体的には、あるユーザーが他のユーザーのページを閲覧した際に FootPrint モデルのオブジェクトを生成し、src と dst それぞれにユーザーの情報をセットし、さらにdate に閲覧したタイミングの現在時刻をセットします(このページの図では date についての記載は省略させていただいています)。

そして、このオブジェクトをレコードとしてデータベースに保存していくイメージになります。

例えば、ユーザー ID が id のユーザーのページを閲覧する際に実行されるビューの関数が other_view であるとすれば、足あと機能を実現するために下記のような処理を行うことになります。
def other_view(request, id):
other = get_object_or_404(User, id=id)
# ログイン中ユーザーが他のユーザーのページを閲覧しようとしている場合に足跡を記録する
if other != request.user:
# ログイン中ユーザーが他のユーザーのページを閲覧しようとしている場合
# FootPrintオブジェクトを生成
footprint = FootPrint(src=request.user, dst=other)
# FootPrintオブジェクトを保存して足あとを記録
footprint.save()
「ログイン中のユーザー」が「ユーザー ID が id のユーザー」のページを閲覧することで other_view が実行される際には、引数 request の user メンバはログイン中ユーザーのオブジェクトとなります。
また、ユーザー ID が id のユーザーは get_object_or_404(User, id=id) の返却値 other として取得することが可能です。
ですので、「ログイン中のユーザー」が「ユーザー ID が id のユーザー」のページを閲覧したという足あとは、引数に src=request.user と dst=other をセットして FootPrint モデルのコンストラクタを実行してやることで生成することができます。さらに、そのオブジェクトに save メソッドを実行させることで、その足あとを記録することができます(date は指定しなくても自動的にコンストラクタ実行時の日時が設定されるようにモデルを定義しています)。
また、上記の例では毎回足あとの情報をデータベースに新規作成していくことになりますが、最新の足あとの情報だけ残すようにしたい場合は、下記のように、同じ src と dst を持つ FootPrint のオブジェクトをまず取得し、そのオブジェクトの date のみを更新してやれば良いです。
def other_view(request, id):
other = get_object_or_404(User, id=id)
# ログイン中ユーザーが他のユーザーのページを閲覧しようとしている場合に足跡を記録する
if other != request.user:
# ログイン中ユーザーが他のユーザーのページを閲覧しようとしている場合
# 同じユーザーに対するFootPrintのオブジェクトを取得
before_footprints = FootPrint.objects.filter(src=request.user, dst=other)
if len(before_footprints) == 0:
# そのような足あとがない場合はFootPrintオブジェクトを生成
footprint = FootPrint(src=request.user, dst=other)
else:
# 既にFootPrintオブジェクトが存在する場合は日時のみ更新
footprint = before_footprints[0]
footprint.date = timezone.now()
# FootPrintオブジェクトを保存して足あとを記録
footprint.save()
ここで、足あと管理用のモデル FootPrint について少し補足しておきます。
当然ですが、ユーザーは複数のユーザーのページを閲覧する可能性があります。つまり、1つの User オブジェクトと複数の FootPrint オブジェクトが関連付けられる可能性があります。この1対多の関連付けができるようにするため、FootPrint の src は ForeignKey としています(OneToOneField ではダメ)。
同様に、ユーザーは複数のユーザーからページを閲覧される可能性があります。そのため、dst に関しても ForeignKey を利用してリレーションフィールドを定義しています。

足あとの情報を表示する
また、足あとの表示に関しては、ユーザーが自身のマイページを表示した際に、そのユーザーのページを表示したユーザー、すなわち、そのユーザーが dst としてセットされている FootPrint のオブジェクト(レコード)をデータベースから取得し、そのオブジェクトの src と date の一覧を表示することで実現することができます。

例えば、ログイン中のユーザーのページを閲覧する際に実行されるビューの関数が user_view であるとすれば、足あとの表示を実現するために下記のような処理を行うことになります。
def user_view(request):
# dstをログイン中ユーザーとするFootPrintを全て取得(dateが新しい順で)
footprints = FootPrint.objects.filter(dst=request.user).order_by('-date')
params = {
'user': request.user,
'footprints' : footprints
}
return render(request, 'footprints/user.html', params)
また、上記の render 関数の引数に指定されている user.html の実装例は例えば下記のようなものになります。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>あなたの情報</title>
</head>
<body>
<h1>{{user.username}}</h1>
<p>連絡先:{{user.email}}</p>
<p>アカウント作成日:{{user.date_joined}}</p>
<h1>{{user.username}}への足跡</h1>
<table class="table-list">
<thead>
<tr>
<th>ユーザー</th><th>日付</th>
</tr>
</thead>
<tbody>
{% for footprint in footprints %}
<tr>
<td><a href="{% url 'other' footprint.src.id %}">{{footprint.src.username}}</a></td>
<td>{{footprint.date|date:"m/d H:i"}}</td>
</tr>
{% empty %}
<tr><td>足跡がありません...</td></tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
足あと機能付きの簡単なウェブアプリのサンプル
足あと機能の実現方法のイメージは付いたでしょうか?
次は、足あと機能付きの簡単なウェブアプリを作成していきたいと思います。
基本的には、下記ページでも紹介しているような「ログイン機能を搭載したウェブアプリ」に対して足あと機能を付け足す形でウェブアプリを作成していきます。
足あと機能以外の実現方法については説明を省略していきますので、ログインの実現方法などで分からない点があれば、別途上記ページを参照していただければと思います。
スポンサーリンク
プロジェクト・アプリの作成
では、足あと機能付きのウェブアプリを開発していきたいと思います。
最初に、いつも通りの手順でプロジェクトとアプリを作成していきます。
まずはターミナル等で適当なフォルダに移動し、下記コマンドを実行してプロジェクト FootPrintsProjectを作成します。
% django-admin startproject FootPrintsProject
上記コマンドにより FootPrintsProject フォルダが作成されますので、そのフォルダに移動してから下記コマンドを実行してアプリ footprints を作成します。
% python manage.py startapp footprints
以降では、パスを示す際には「現在いるフォルダからの相対パス」で表記させていただきます。
各種設定
続いて、プロジェクトの設定と URL とビューの関連付けの設定を行なっていきます。
プロジェクトの設定
まずはプロジェクトの設定を行なっていきます。
FootPrintsProject/settings.py を開き、INSTALLED_APPSを下記のように変更してプロジェクトにアプリの登録を行いましょう(最初に 'footprints', を追記する)。
INSTALLED_APPS = [
'footprints', # 追記
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
続いて、TIME_ZONE の設定を下記のように変更し、タイムゾーンを日本時間に合わせます。
TIME_ZONE = 'Asia/Tokyo'
それから、ファイルの最後に下記を追記し、ログインページを /footprints/login/ に設定します。これにより、「ログインユーザー以外からのアクセスを禁止しているページ」に対して非ログインユーザーがアクセスしてした際に、自動的に /footprints/login/ にリダイレクトされるようになります。
LOGIN_URL = '/footprints/login/'
URL とビューの関連付け
続いて URL とビューの関連付けを行なっていきます。
まずは、FootPrintsProject/urls.py を下記のように変更します。これにより、リクエストされた URL(ルートパス指定で考えた時の URL)が /footprints/ から始まる場合に、 footprints/urls.py が読み込まれるようになります。
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('footprints/', include('footprints.urls')),
]
続いて、その読み込み先となる footprints/urls.py を下記のように新規作成します。
from . import views
from django.urls import path
urlpatterns = [
path('signup/', views.signup_view, name='signup'),
path('login/', views.login_view, name='login'),
path('logout/', views.logout_view, name='logout'),
path('user/', views.user_view, name='user'),
path('others/', views.others_view, name='others'),
path('other/<int:id>/', views.other_view, name='other'),
]
これにより、path の第1引数に指定した URL へのリクエストがあった際には path の第2引数に指定したビューの関数が実行されるようになります。
ただし、これらのビューの関数はまだ作成していないため、現状だとウェブアプリを実行しようとするとエラーになります。このエラーは、以降の手順でビュー等を作成していくことで解消していきます。
モデルの作成
ここまでの手順でウェブアプリの設定は完了です。
ここからは、ウェブアプリのコアの部分となるモデル・フォーム・ビュー・テンプレートを作成していきます。
まず作成するのはモデルです。
足あとを管理することができるように、footprints/models.py を下記のように変更しましょう!
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
class FootPrint(models.Model):
src = models.ForeignKey(User, on_delete=models.CASCADE, related_name='src_footprint')
dst = models.ForeignKey(User, on_delete=models.CASCADE, related_name='dst_footprint')
date = models.DateTimeField(default=timezone.now)
この FootPrintは 足あと用のモデルを作成する で紹介した「誰が(src)誰の(dst)ページを閲覧したか」の情報を管理するモデルになります。さらに、「いつ閲覧したか」の情報も管理できるように date フィールドも持たせており、デフォルトでオブジェクト生成時の日時が記録されるようになっています。
また、src と dst の両方において User と FootPrint との間には1対多の関連付けができるようにしています。

さらに、FootPrint オブジェクトの src データ属性から「閲覧元のユーザーに対する User オブジェクト」に、また FootPrint オブジェクトの dst データ属性から「閲覧先のユーザーに対する User オブジェクト」にアクセスすることが可能です。

詳細な説明は省略しますが、User オブジェクトから FootPrint オブジェクトに対してアクセスを行うことも可能です。具体的には、User 自身が src に設定されている FootPrint オブジェクトは .src_footprint から、User 自身が dst に設定されている FootPrint オブジェクトは .dst_footprint からアクセスが可能です。
スポンサーリンク
フォームの作成
モデルの作成後はフォームの作成を行なっていきます。
といっても、今回用意するのはユーザー登録用のフォームとログイン用のフォームであり、つまりは用意するフォームはログインを実現するためのフォームのみとなります。足あと機能には直接関係するものではないため、今回は詳細な説明は省略いたします。
ユーザー登録用のフォームとログイン用のフォームは、次のように footprints/forms.py を新規作成することで実現することができます。
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
class SignupForm(UserCreationForm):
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
class LoginForm(AuthenticationForm):
pass
ビューの作成
続いてビューを作成していきます。
定義する関数
ビューにおいては、footprints/urls.py において path の第2引数にも指定した下記の6つの関数を定義していきます。各関数で行うことは関数名の右側に簡単に記載しています。
signup_view:ユーザー登録を行うlogin_view:ログインを行うlogout_view:ログアウトを行うuser_view:ログイン中のユーザーのページを表示するothers_view:登録されているユーザー一覧を表示する(ログイン中のユーザーを除いて)other_view:指定されたidに対応するユーザーのページを表示する
user_view ではログイン中のユーザーを dst とする「足あとの情報一覧の表示」も行います。そのため、user_view から作成する HTML に足あとの情報一覧が表示されるよう、足あとの表示を実現するためのテンプレートも用意する必要があります。このテンプレートについては次の テンプレートの作成 で紹介します。
また、other_view は、基本的にはログイン中のユーザーが他のユーザー(指定された id のユーザー)のページを表示する際に実行される関数となります。

そのため、この other_view では「足あとの記録」、すなわち FootPrint のオブジェクトの生成 or 更新とデータベースへの保存を行います。さらに、他のユーザーのページにも「足あとの情報一覧」が表示されるようにしていきます。
本来、足あとは他のユーザーからは閲覧できないよう、マイページのみに表示する方が良いのですが、他のユーザーのページ表示時に足あとが確認できた方がアプリの動作確認をしやすいため、今回はこのような仕様としています。
views.py の実装
上記のような6つの関数を定義したビューは、次のように footprints/views.py を定義することで実現することができます。
from django.shortcuts import render, redirect, get_object_or_404
from .forms import SignupForm, LoginForm
from .models import FootPrint
from django.contrib.auth import login, logout
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.utils import timezone
def signup_view(request):
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect(to='/footprints/user/')
else:
form = SignupForm()
param = {
'form': form
}
return render(request, 'footprints/signup.html', param)
def login_view(request):
if request.method == 'POST':
form = LoginForm(request, data=request.POST)
if form.is_valid():
user = form.get_user()
if user:
login(request, user)
return redirect(to='/footprints/user/')
else:
form = LoginForm()
param = {
'form': form,
}
return render(request, 'footprints/login.html', param)
def logout_view(request):
logout(request)
return render(request, 'footprints/logout.html')
@login_required
def user_view(request):
# dstをログイン中ユーザーとするFootPrintを全て取得(dateが新しい順で)
footprints = FootPrint.objects.filter(dst=request.user).order_by('-date')
params = {
'user': request.user,
'footprints' : footprints
}
return render(request, 'footprints/user.html', params)
@login_required
def other_view(request, id):
other = get_object_or_404(User, id=id)
# ログイン中ユーザーが他のユーザーのページを閲覧しようとしている場合に足跡を記録する
if other != request.user:
# ログイン中ユーザーが他のユーザーのページを閲覧しようとしている場合
# 同じユーザーに対するFootPrintのオブジェクトを取得
before_footprints = FootPrint.objects.filter(src=request.user, dst=other)
if len(before_footprints) == 0:
# そのような足あとがない場合はFootPrintオブジェクトを生成
footprint = FootPrint(src=request.user, dst=other)
else:
# 既にFootPrintオブジェクトが存在する場合は日時のみ更新
footprint = before_footprints[0]
footprint.date = timezone.now()
# FootPrintオブジェクトを保存して足あとを記録
footprint.save()
# dstを閲覧先のユーザーとするFootPrintを全て取得(dateが新しい順で)
footprints = FootPrint.objects.filter(dst=other).order_by('-date')
params = {
'other': other,
'footprints' : footprints
}
return render(request, 'footprints/other.html', params)
@login_required
def others_view(request):
others = User.objects.exclude(username=request.user.username)
params = {
'others': others,
}
return render(request, 'footprints/others.html', params)
前述の通り、user_view と other_view とが足あと機能を実現する上でポイントになる関数になります。
user_view と other_view 共に「足あとの情報の一覧表示」を行う関数であり、これらの関数の中で閲覧先のユーザーが dst に設定された FootPrint オブジェクトを全て取得し、それらをテンプレートに渡すようにしています。
また、other_view では「足あとの記録」も行う必要があります。詳細については other_view の処理やコメントを読んでいただければと思いますが、あるユーザーが他のユーザーのページを一度閲覧したことがある場合は、それらのユーザーを src と dst にセットした FootPrint オブジェクト(レコード)が既にデータベースに保存されているはずです。ですので、この場合はデータベースからオブジェクトとして取得し、そのオブジェクトの date のみを更新してデータベースに保存するようにしています。
逆に、 あるユーザーが他のユーザーのページを初めて閲覧する場合は、それらのユーザーを src と dst にセットした FootPrint オブジェクト(レコード)はデータベースに存在しないため、この場合は FootPrint オブジェクトを新たに生成し、その FootPrint オブジェクトのデータベースへの保存を行なっています。
テンプレートの作成
次は、実装の最後としてテンプレートを作成していきます。
作成するテンプレートファイル
ビューの作成 で関数を6つ定義しましたが、各関数からは render 関数が実行され、その際に引数で利用するテンプレートファイルが指定されています。
このビューから利用されている下記の6つのテンプレートファイルを作成していきます。
signup.html:ユーザー登録ページ表示用login.html:ログインページ表示用logout.html:ログアウトページ表示用user.html:ログイン中のユーザーのページ表示用others.html:登録されているユーザー一覧ページ表示用other.html:指定されたidに対応するユーザーのページ表示用
これらのテンプレートがビューから受け取るデータに関しては ビューの作成 で定義した関数の処理をご参照いただければと思います(render 関数の第3引数に指定されたデータがテンプレートに渡されます)。
これらのファイルは footprints/templates/footprints フォルダの中に新規作成していく必要があります。おそらく、まだこのフォルダは存在しないはずなので、テンプレートファイルを作成していく前に必要なフォルダを作成しておいてください。
テンプレートファイルの実装
それでは、各種テンプレートファイルの実装例を示していきます。
signup.html の実装例は下記のようになります。
{% load static %}
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>ユーザー登録</title>
</head>
<body>
<h1>ユーザー登録</h1>
<form action="{% url 'signup' %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<p><input type="submit" value="登録"></p>
</form>
</body>
</html>
login.html の実装例は下記のようになります。
{% load static %}
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>ログイン</title>
</head>
<body>
<h1>ログイン</h1>
<form action="{% url 'login'%}" method="post">
{% csrf_token %}
{{ form.as_p }}
<p><input type="hidden" name="next" value="{{next}}"></p>
<p><input type="submit" value="ログイン"></p>
</form>
<p><a href="{% url 'signup'%}">ユーザー登録</a></p>
</body>
</html>
logout.html の実装例は下記のようになります。
{% load static %}
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>ログアウト</title>
</head>
<body>
<p>ログアウトしました...</p>
<p><a href="{% url 'login'%}">ログイン</a></p>
</body>
</html>
user.html の実装例は下記のようになります。
{% load static %}
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>あなたの情報</title>
</head>
<body>
<h1>{{user.username}}</h1>
<p>連絡先:{{user.email}}</p>
<p>アカウント作成日:{{user.date_joined}}</p>
<h1>{{user.username}}への足跡</h1>
<table class="table-list">
<thead>
<tr>
<th>ユーザー</th><th>日付</th>
</tr>
</thead>
<tbody>
{% for footprint in footprints %}
<tr>
<td><a href="{% url 'other' footprint.src.id %}">{{footprint.src.username}}</a></td>
<td>{{footprint.date|date:"m/d H:i"}}</td>
</tr>
{% empty %}
<tr><td>足跡がありません...</td></tr>
{% endfor %}
</tbody>
</table>
<p><a href="{% url 'others'%}">他のユーザー一覧</a></p>
<p><a href="{% url 'logout'%}">ログアウト</a></p>
</body>
</html>
user.html は足あと機能を実現する上でポイントになるテンプレートの1つであるため、少し補足で説明をしておきます。
上記の user.html では足あとの情報の表示を行なっており、足あとの情報としてはログイン中のユーザーのページを閲覧したユーザーの一覧を示しています(ユーザー名と足あとが記録された日時を表示)。
モデルの作成 でも説明したように、この閲覧したユーザーに対する User オブジェクトには FootPrint のオブジェクトの src データ属性からアクセスすることができ、そのアクセスした User オブジェクトの username データ属性を表示することで、誰がログイン中のユーザーのページを閲覧したのかを表示するようにしています。
では、再度テンプレートの実装例の紹介を行なっていきたいと思います。others.html の実装例は下記のようになります。
{% load static %}
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>他のユーザー</title>
</head>
<body>
<h1>他のユーザー</h1>
<table>
<thead>
<tr>
<th>ユーザー</th>
</tr>
</thead>
<tbody>
{% for other in others %}
<tr>
<td><a href="{% url 'other' other.id %}">{{other.username}}</a></td>
</tr>
{% empty %}
<tr><td>他のユーザーがいません...</td></tr>
{% endfor %}
</tbody>
</table>
<p><a href="{% url 'user'%}">あなたの情報</a></p>
<p><a href="{% url 'logout'%}">ログアウト</a></p>
</body>
</html>
other.html の実装例は下記のようになります。
{% load static %}
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>{{other.username}}の情報</title>
</head>
<body>
<h1>{{other.username}}の情報</h1>
<h2>{{other.username}}</h2>
<p>連絡先:{{other.email}}</p>
<h1>{{other.username}}への足跡</h1>
<table class="table-list">
<thead>
<tr>
<th>ユーザー</th><th>日付</th>
</tr>
</thead>
<tbody>
{% for footprint in footprints %}
<tr>
<td><a href="{% url 'other' footprint.src.id %}">{{footprint.src.username}}</a></td>
<td>{{footprint.date|date:"m/d H:i"}}</td>
</tr>
{% empty %}
<tr><td>足跡がありません...</td></tr>
{% endfor %}
</tbody>
</table>
<p><a href="{% url 'user'%}">あなたの情報</a></p>
<p><a href="{% url 'logout'%}">ログアウト</a></p>
</body>
</html>
other.html でも user.html 同様に足あとの情報の表示を行なっています。ポイントは user.html の実装例を紹介した後に説明していますので、ここでの説明は省略します。
スポンサーリンク
マイグレーションの実施
以上で実装は完了です。
最後にマイグレーションを実行すれば、アプリを動作させる準備が完了します。
いつも通り、下記のようにコマンドを実行してマイグレーションを行いましょう!
% python manage.py makemigrations % python manage.py migrate
これで、footprints/models.py に基づいたテーブルがデータベースに作成されることになります。
ちょっとここで、この作成されるテーブルについて補足しておくと、今回用意した footprints/models.py の場合、下の図のような id・date・src_id・dst_id をカラムとして持つテーブルが作成されることになります。

最初はテーブルの中身は空ですが、other_view で FootPrint オブジェクトに save メソッドを実行させれば、このテーブルの各列の項目名をフィールドとして持つレコードが追加(もしくは更新)されることになります。
より具体的には、id フィールドに FootPrint オブジェクト自体の ID、date フィールドに FootPrint オブジェクトが作成された(or 更新された)日時の情報、src_id フィールドにページを閲覧したユーザー(足あとをつけたユーザー)の ID、dst_id フィールドにページを閲覧されたユーザー(足あとをつけられたユーザー)の ID がそれぞれセットされた状態のレコードが保存されることになります。

そして、このようなレコードがデータベースに保存されることで足あとの情報が管理できるようになり、さらにデータベースからレコードを取得すれば足あとを表示することも可能となります。
ちなみに、こういったデータベースの確認は、例えば VSCode であればプラグインの利用により簡単に行うことができます。
この辺りは下記ページで解説していますので、興味があれば是非読んでみてください。
動作確認
最後に作成したアプリの動作確認を行なっておきましょう!
まずは、下記コマンドを実行して Django 開発用ウェブサーバーを起動します。
% python manage.py runserver
さらに、ウェブブラウザで下記 URL を開きます。
http://localhost:8000/footprints/signup/
すると、下の図のようなユーザー登録画面に遷移するはずですので、ユーザー名とメールアドレス、さらにはパスワードを入力してユーザーを登録します。

ユーザー登録に成功すればログインが自動的に行われ、その後下の図のようなログイン中のユーザーの情報を表示するページに遷移するはずです。

これでユーザーの登録は完了したのですが、今回は足あと機能の動作確認を行う必要があり、足あとを付けるためには他のユーザーが必要になります。
そのため、もう一人のユーザーを登録するために、再度下記 URL をウェブブラウザで開きます。
http://localhost:8000/footprints/signup/
そして、表示されるユーザー登録ページで再度ユーザーの登録を行います。先ほど登録したユーザーとは異なるユーザー名を指定してユーザーを登録してください。
ユーザー登録すれば再びログインが行われ、新たに作成したユーザーの情報を表示するページに遷移します。

これで、足あと機能の動作確認を行う上で最低限必要な数のユーザーが登録されたことになりますので、次は実際に足あとの記録や足あとの表示を行なっていきましょう!
まず、今いるページの下側にいる 他のユーザー一覧 リンクをクリックします。
これによりログイン中ユーザー以外のユーザーの一覧が表示されます。ここでは最初に登録したユーザーが表示されているはずですので、ユーザー名をクリックしてそのユーザーのページを閲覧します。

これにより、最初に登録したユーザーの情報の表示ページが表示されます。注目していただきたいのがページ下側の「足あとの情報」です。
ここでは、最初に登録したユーザーのページに対する足あとの情報が表示されています。
今回は二人目に登録したユーザーが最初に登録したユーザーのページを閲覧しているわけですから、二人目に登録したユーザーの名前と閲覧した日時が表示されているはずです。

また、ちょっと時間を空けてから再度最初に登録したユーザーのページを表示すれば足あとの日時が更新されていることも確認できると思います。

こんな感じで、ユーザーが他のユーザーのページを閲覧する度に足あとの記録 or 更新が行われることになります。
そして、前述でも解説したように、足あとの記録や更新は other_view で実行されています。
ここでは説明を簡単にさせていただくために登録するユーザー数は2人のみとしていますが、登録するユーザーを増やし、さらにいろんなユーザーのページを訪れてみれば、足あとがどんどん増えていくことも確認できると思います!

また、最初に登録したユーザーで再度ログインを行えば、今度は自身のページ(user_view が実行されて表示されるページ)で他のユーザー(二人目に登録したユーザー等)からの足あとの情報も確認することも可能になります。
まとめ
このページでは、Django を利用した「足あと」機能の実現方法について解説しました!
もしかしたら若い方は「足あと」機能をご存知ないかも知れませんが、このページを読んで機能の概要や実現方法について理解していただけたのではないかと思います。
「Django の入門書は読み終わったけど次何を勉強すれば良いか思いつかない…」という方も多いのではないかと思いますが、今回の例のように実際のウェブアプリに搭載されている機能を自分の手で実現してみると勉強にもなりますし、よりウェブアプリや Django への興味も深くなると思います!
是非いろんな機能の実現に挑戦してみてください!

