@kyanny's blog

我々の目的は何かと聞かれて、私はたった一つの言葉で答えることができる。勝利。それだけだ - ウィンストン・チャーチル

Django: FileField が admin でリンクになる理由

django.db.models.FileField と django admin を使って作ったファイルアップロードフォームを使うと、ファイル名がアップロードしたファイルへのリンクになる*1

↓NAME 列の fruits.csv がリンクになっている

https://user-images.githubusercontent.com/10515/104941840-ee505100-59f6-11eb-93cc-51c2d4f8a243.png

models.py

from django.db import models

# Create your models here.
class Upload(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.FileField()

admin.py

from django.contrib import admin
from .models import Upload

# Register your models here.
class UploadAdmin(admin.ModelAdmin):
    list_display = ('id', 'name',)


admin.site.register(Upload, UploadAdmin)

どういう仕組みで自動的にリンク (a タグ) が作られるか気になったので調べた。

つまり、 FileField がリンクになるのを防ぐことはできない。

(実は、リンクにしない方法が無いか調べていて、そもそもなぜリンクになるんだろう?リンクになる仕組みがわかれば、コントロールする方法も見つかるのでは?と考えて調べた)

サンプルプロジェクトは

https://github.com/kyanny/django-model-filefield

に置いた。


なお、この調査のとっかかりとしては、 rg -g '*.py' 'field-' で django/contrib/admin 以下を雑に検索して https://github.com/django/django/blob/3.1.5/django/contrib/admin/templatetags/admin_list.py#L231 を見つけ、周囲のコードを読んで条件分岐を一つずつ調べていって display_for_field の呼び出しが当たりかな、と見当をつけた。

これに限らず、ある程度大きなライブラリやフレームワークの調査をするときは、(ドキュメントやウェブ検索で解決しない場合は)ログメッセージとか出力する HTML コードの特徴的な部分*2でソースコードを grep して当たりをつける、というやり方を渋々、仕方なくやることが多いが、泥臭くて非効率なやり方だという自覚がある。みんなどういう風に調べているんだろうか。

*1:ただし MEDIA_ROOT や urls.py を適切に設定しないと実際のファイルにアクセスできない。

*2:id, class など