django.db.models.FileField と django admin を使って作ったファイルアップロードフォームを使うと、ファイル名がアップロードしたファイルへのリンクになる*1。
↓NAME 列の fruits.csv がリンクになっている
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 タグ) が作られるか気になったので調べた。
- django/contrib/admin/templatetags/admin_list.py の items_for_result の中で display_for_field を呼んでいる
- display_for_field の中で FileField の場合 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 して当たりをつける、というやり方を渋々、仕方なくやることが多いが、泥臭くて非効率なやり方だという自覚がある。みんなどういう風に調べているんだろうか。