instance.id
在通过管理页面上传图像时返回None
。我们的想法是将每个住宅的所有图像上传到不同的文件夹。这是我的代码:
models.py
from django.db import models
import os
def get_image_path(instance, filename):
return os.path.join('photos', "residence_%s" % instance.id, filename)
# Create your models here.
class Residence(models.Model):
big_image = models.ImageField("Main Image",upload_to=get_image_path)
small_images = models.ImageField("Small Images",upload_to=get_image_path, blank=True, null=True)
settings.py
MEDIA_URL = '/media/'
编辑:如果我在添加模型后修改图像,它可以工作。
除非您实现自定义动态文件上传字段,否则无法以这种方式执行此操作。因为您尝试访问instance.id
,但instance
尚未保存并且没有id
。
这里有一些资源可以帮助您实现您想要的:
- 具有当前实例 ID 的动态文件上传路径
- 使用当前模型 ID 上传 Django 管理文件
解决此问题的另一种需要更少代码的好方法是让模型使用UUID作为主键,而不是数据库生成的id。这意味着在模型首次保存时,UUID 已经已知,并且可以与任何upload_to
回调一起使用。
所以对于原始示例,你会做这样的事情
from django.db import models
import uuid
import os
def get_image_path(instance, filename):
return os.path.join('photos', "residence_%s" % str(instance.id), filename)
# Create your models here.
class Residence(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
big_image = models.ImageField("Main Image",upload_to=get_image_path)
small_images = models.ImageField("Small Images",upload_to=get_image_path, blank=True, null=True)
参见 Django 的 UUIDField 参考以获取更多信息
如果您没有在ImageField
上指定update_to
,则可以上传到媒体根目录,然后使用post_save
信号更改路径。
@receiver(post_save, sender=Product)
def update_file_path(instance, created, **kwargs):
if created:
initial_path = instance.image.path
new_path = settings.MEDIA_ROOT + f'/product_{instance.id}/{instance.image.name}'
os.makedirs(os.path.dirname(new_path), exist_ok=True)
os.rename(initial_path, new_path)
instance.image = new_path
instance.save()
通过将清理的数据从表单作为**kwargs传递给Django模型来创建模型实例 我是这样做的,它比其他任何事情都容易得多
在您的视图中 发布方法 添加这个(此代码来自我的项目,不适用于此问题)
pk = request.session['_auth_user_id']
user_obj = User.objects.get(pk=pk)
lab_form_instance = lab_form(request.POST,request.FILES)
lab_form_instance.save(commit=False)
# here you can put the form.is_valid() statement
lab_form_instance.cleaned_data['owner'] =user_obj # here iam adding additional needed data for the model
obj = lab(**lab_form_instance.cleaned_data)
obj.save()