You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Django数据库中存储的图片生成带有效期的访问URL

Django 实现有时效性的图片访问链接方案

1. 创建临时链接存储模型

你需要新增一个数据库模型,用来关联Photo表、存储链接校验凭证和过期时间:

import uuid
from django.db import models
from django.utils import timezone
from datetime import timedelta
# 引入你已经定义的Photo模型
from .models import Photo

class TemporaryPhotoLink(models.Model):
    # 关联原图片表
    photo = models.ForeignKey(Photo, on_delete=models.CASCADE, null=False, blank=False)
    # 唯一访问凭证,避免链接被遍历
    access_token = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
    # 过期时间
    expire_at = models.DateTimeField(null=False, blank=False)
    # 可选字段:控制是否单次访问后就失效,不需要可以删除
    is_used = models.BooleanField(default=False)

    # 校验链接是否有效的方法
    def is_valid(self):
        return not self.is_used and timezone.now() < self.expire_at

    # 快速生成临时链接的类方法
    @classmethod
    def generate_for_photo(cls, photo, expire_seconds=500):
        expire_time = timezone.now() + timedelta(seconds=expire_seconds)
        return cls.objects.create(photo=photo, expire_at=expire_time)

执行python manage.py makemigrations和python manage.py migrate创建对应数据库表。

2. 配置临时链接生成逻辑

首先在项目urls.py中新增临时链接的路由规则:

from django.urls import path
from . import views

urlpatterns = [
    # 你的其他路由
    path('temp-photo/<uuid:token>/', views.temp_photo_access, name='temp_photo_access'),
]

需要生成链接时调用以下逻辑即可获得有效期500秒的访问地址:

from django.urls import reverse

# 传入需要生成链接的Photo实例
def get_temporary_photo_url(photo):
    temp_link = TemporaryPhotoLink.generate_for_photo(photo)
    # 拼接得到完整访问链接
    return reverse('temp_photo_access', args=[str(temp_link.access_token)])

3. 实现访问验证视图

新增视图函数处理临时链接的访问校验,有效则返回图片资源,无效返回404:

from django.http import HttpResponse, Http404
from django.shortcuts import get_object_or_404
from django.conf import settings
import os

def temp_photo_access(request, token):
    temp_link = get_object_or_404(TemporaryPhotoLink, access_token=token)
    # 校验链接有效性
    if not temp_link.is_valid():
        raise Http404("链接已过期或失效")
    
    # 不需要单次访问失效的话可以删掉下面两行
    temp_link.is_used = True
    temp_link.save()

    # 生产环境建议用Nginx X-Accel-Redirect/Apache X-Sendfile处理文件响应,降低Django压力
    photo_path = os.path.join(settings.MEDIA_ROOT, temp_link.photo.photo.name)
    with open(photo_path, 'rb') as f:
        response = HttpResponse(f.read(), content_type="image/jpeg")
        response['Content-Disposition'] = 'inline; filename=' + os.path.basename(photo_path)
        return response

4. 优化建议

  • 定期清理已经过期的TemporaryPhotoLink记录,可以写Django管理命令结合crontab定时执行,避免无效数据占用数据库空间
  • 如果你使用云存储(阿里云OSS、腾讯云COS、AWS S3等),可以直接使用云存储自带的签名URL功能,不需要自行维护临时链接表,直接指定过期时间即可,性能更高、维护成本更低

内容的提问来源于stack exchange,提问作者azarjaved

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 08:06:03