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
相关产品推荐
相关产品推荐

