Django按对象ID命名文件夹上传文件的问题及解决尝试
Django上传图片到对象ID命名文件夹的问题解决过程
我想实现将产品图片上传到以产品ID命名的文件夹中,但实际生成的文件夹名称是None而非产品的ID。查资料后发现,这是因为文件夹路径在对象完全创建前就已生成,此时对象的ID还未被数据库分配。
初始代码(models.py)
def getImageURL(self, filename): return "products_images/" + str(self.pk) + "/product_image.png" class Product(models.Model): name = models.CharField(max_length=200) image = models.ImageField(upload_to=getImageURL, default="media/static/products_images/default.png" )
第一次修改及问题
我把函数改成了接收instance参数的形式:
def getImageURL(instance, filename): return "products_images/{}/product_image.png".format(instance.id)
但这个方法只在编辑已有对象时生效,新建对象时instance.id还是None,文件夹名依然不对。
最终实现方案
我采用了提前获取下一个ID的方式,虽然可能不是最优解,但逻辑简单易懂,暂时先用这个方案:
def getFileNumber(): queryset = Product.objects.all().order_by('pk') last = queryset.last() last_id = last.id file_number = last_id+1 return str(file_number) def getImageURL(instance, filename): return "products_images/{}/product_image.png".format(getFileNumber()) class Product(models.Model): name = models.CharField(max_length=200) category = models.ForeignKey(Category, on_delete=models.CASCADE) availability = models.IntegerField() price = models.DecimalField(max_digits=5, decimal_places=2)
调试版本代码
为了处理空数据库和重复文件的情况,我写了调试版本的代码:
import os def getFileNumber(): queryset = Product.objects.all().order_by('pk') if queryset: last = queryset.last() last_id = last.id file_number = last_id+1 return str(file_number) else: file_number=1 return str(file_number) def getImageURL(instance, filename): path = os.path.join("products_images/{}/product_image.png".format(getFileNumber())) print(path) if os.path.isfile("media/" + path): print("image with this id already exist, ") os.remove("media/" + path) return path else: return path class Product(models.Model): name = models.CharField(max_length=200) category = models.ForeignKey(Category, on_delete=models.CASCADE) availability = models.IntegerField() price = models.DecimalField(max_digits=5, decimal_places=2)
内容的提问来源于stack exchange,提问作者KermitHQ
相关产品推荐
相关产品推荐

