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

Django中如何通过ForeignKey获取关联表字段值生成上传文件路径

问题根因

你当前的写法直接引用了Camera类的slug属性,拿到的是Django模型字段的描述对象(也就是你路径里的DeferredAttribute对象),不是具体关联记录的实际字段值,所以路径生成异常。

解决方案

Django的ImageField的upload_to参数支持传入可调用对象,该对象会在文件上传时触发调用,自动传入当前要保存的BaseImage实例、上传的原始文件名两个参数,你可以在这个函数中动态获取关联的Camera的slug值,生成你需要的路径。

修改后的完整代码如下:

import datetime
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator

def get_base_image_upload_path(instance, filename):
    # 获取关联Camera的slug值
    camera_slug = instance.url.slug
    # 生成小时格式的路径片段
    current_hour = datetime.datetime.now().strftime("%H")
    # 拼接返回完整的存储路径
    return f"base_images/{camera_slug}/{current_hour}/{filename}"

class Camera(models.Model):
    url = models.CharField(max_length=300, unique=True)
    camera_number = models.IntegerField(null=False, blank=False,
                                        validators=[
                                          MaxValueValidator(1000),
                                          MinValueValidator(1)])
    camera_name = models.CharField(max_length=100, null=False, blank=False)
    slug = models.SlugField(max_length=100, null=True, blank=False, unique=True)


class BaseImage(models.Model):
    url = models.ForeignKey(Camera, on_delete=models.CASCADE)
    # upload_to传入上面定义的函数,无需加括号
    image = models.ImageField(max_length=300, upload_to=get_base_image_upload_path)

注意事项

  • 保存BaseImage实例前,必须先给url字段赋值对应的Camera实例,否则会因无法获取slug抛出异常
  • 若后续Camera的slug字段值发生变更,已经上传的文件路径不会自动更新,若需要同步修改需要额外编写逻辑处理已存文件和数据库记录

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:36:00