Вы можете относительно легко загрузить файл в Django и сохранить его в месте в вашей файловой системе, используя Model
. И вполне стандартно настроить обслуживание этих загруженных файлов, когда пользователям нужно их просмотреть.
Исключительно специфический, но, как мне кажется, распространенный случай — это когда эти файлы могут просматривать только администраторы. Например, если пользователю необходимо загрузить проверочный документ, который администраторы должны просмотреть, прежде чем предоставить пользователю полный доступ.
В таких случаях стандартного процесса настройки развертывания статических файлов может быть недостаточно. Эти загруженные медиафайлы должны быть доступны для загрузки только из интерфейса администратора. Давайте посмотрим, как это можно сделать с помощью пользовательского представления администратора.
Предварительные условия
Во-первых, вам необходимо настроить пользовательский сайт администратора, как описано здесь.
Во-вторых, ваша модель должна содержать поле FileField
:
class CustomUserProfile(models.Model):
# [...] Other fields
id_proof = models.FileField(upload_to='id_proof')
models.py
Представление
Вам понадобится представление, которое будет принимать в качестве параметра первичный ключ объекта и возвращать байты файла. Для этого подойдет HttpResponse
с содержимым файла и некоторыми дополнительными заголовками.
class IdProofView(View):
def get(self, request, pk):
user_profile = CustomUserProfile.objects.get(pk=pk)
filename = os.path.basename(user_profile.id_proof.name)
response = HttpResponse(user_profile.id_proof)
response['Content-Disposition'] =
f'attachment; filename={filename}'
return response
views.py
Затем подключите его к URL-диспетчеру вашего пользовательского администратора (см. здесь, как настроить пользовательский администратор сайта). Обратите внимание, что вы оборачиваете вызов вашего представления командой admin_view()
. Это защитит его от несанкционированного доступа. Только сотрудники смогут загрузить файл, а это именно то поведение, которое нам нужно.
class CustomAdminSite(AdminSite):
def get_urls(self):
urls = super().get_urls()
my_urls = [
# [...] Other views for your custom admin
path('id_proof/<int:pk>',
self.admin_view(IdProofView.as_view()), name='id_proof'),
]
return my_urls + urls
admin.py
ModelAdmin
Наконец, нам нужно показать «защищенную» ссылку на файл в интерфейсе администратора. Нам нужен ModelAdmin
, который генерирует ссылку, если она существует, и показывает ее как свойство только для чтения. Как вариант, можно скрыть поле по умолчанию в ModelAdmin
, которое все равно не будет работать, если вы не настроили обслуживание медиафайлов.
class CustomUserProfileModelAdmin(admin.ModelAdmin):
readonly_fields = ('id_proof_url',)
exclude = ('id_proof',)
def id_proof_url(self, instance):
if instance.id_proof is None:
return '-'
return format_html(
f'<a href="{reverse("admin:id_proof",
kwargs={"pk": instance.pk})}"target="_blank">Download</a>',
)
admin.register(CustomUser, CustomUserModelAdmin)
admin.py
Надеемся, вы получили представление о том, как безопасно обслуживать файлы, определенные в моделях, для пользователей персонала через интерфейс администратора.
Успешного кодинга!