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

DRF中为图片生成自定义过期时间的临时链接方案咨询

解决方案建议

一、是否需要新建模型存储临时链接?

必须单独新建模型,这是更合理的设计:

  • 原Image模型专注存储图片核心信息,临时链接属于附加访问凭证,分离职责符合单一原则。
  • 支持为同一张图片生成多个不同过期时间的临时链接,互不干扰。

示例模型代码:

from django.db import models
from django.utils import timezone
from .models import Image

class TemporaryImageLink(models.Model):
    image = models.ForeignKey(Image, on_delete=models.CASCADE, related_name="temp_links")
    hash_key = models.CharField(max_length=64, unique=True)  # 哈希编码的链接唯一标识
    expire_time = models.DateTimeField()  # 用户设置的过期时间
    created_at = models.DateTimeField(default=timezone.now)
    
    def is_expired(self):
        return timezone.now() > self.expire_time

二、哈希编码链接的实现

用哈希生成唯一且不易被猜测的hash_key,避免非法访问:

  • 结合图片ID、时间戳、随机字符串生成原始数据,再通过SHA-256生成哈希值。
  • 示例生成逻辑:
import hashlib
import random
import string
from django.utils import timezone

def generate_temp_link_hash(image_id):
    random_str = ''.join(random.choices(string.ascii_letters + string.digits, k=16))
    raw_data = f"{image_id}-{timezone.now().timestamp()}-{random_str}"
    return hashlib.sha256(raw_data.encode()).hexdigest()

生成的链接格式可以设计为/temp-image/<hash_key>/,后端通过hash_key匹配到对应TemporaryImageLink,校验过期状态后返回图片内容。

三、自动删除过期对象的方案

1. Django第三方定时任务库(轻量场景推荐)

使用django-background-tasks或django-q实现定时清理:

  • 安装库后创建清理任务:
from background_task import background
from .models import TemporaryImageLink
from django.utils import timezone

@background(schedule=3600)  # 每小时执行一次清理
def clean_expired_temp_links():
    expired_links = TemporaryImageLink.objects.filter(expire_time__lt=timezone.now())
    expired_links.delete()
  • 项目启动时触发一次任务,后续会自动按设定间隔执行。

2. 系统级定时任务(生产环境首选)

在Linux服务器通过crontab调用Django自定义管理命令:

  • 先在app的management/commands目录下创建clean_expired_links.py:
from django.core.management.base import BaseCommand
from django.utils import timezone
from .models import TemporaryImageLink

class Command(BaseCommand):
    help = '清理过期的临时图片链接'

    def handle(self, *args, **options):
        count, _ = TemporaryImageLink.objects.filter(expire_time__lt=timezone.now()).delete()
        self.stdout.write(self.style.SUCCESS(f"成功删除{count}条过期链接"))
  • 配置crontab定时任务(比如每天凌晨2点执行):
0 2 * * * /path/to/venv/bin/python /path/to/project/manage.py clean_expired_links

3. 访问时惰性清理(补充方案)

处理临时链接请求时,顺带清理过期记录,避免无效数据堆积:

from django.shortcuts import get_object_or_404
from django.http import HttpResponse
from .models import TemporaryImageLink

def temp_image_view(request, hash_key):
    temp_link = get_object_or_404(TemporaryImageLink, hash_key=hash_key)
    if temp_link.is_expired():
        temp_link.delete()
        return HttpResponse("链接已过期", status=410)
    # 返回图片内容
    return HttpResponse(temp_link.image.image.read(), content_type='image/jpeg')

四、额外注意事项

  • 权限校验:生成临时链接时,必须验证当前用户是对应图片的所有者。
  • 文件清理:如果临时链接删除后图片无其他保留价值,可在删除TemporaryImageLink时判断图片是否还有有效关联,再决定是否删除图片文件。
  • 缓存优化:对访问量高的临时链接,可缓存其过期状态,减少数据库查询次数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 00:35:22