【问题标题】:Python Django: How to upload a file with a filename based on instance pkPython Django:如何根据实例pk上传文件名的文件
【发布时间】:2023-03-22 12:48:01
【问题描述】:

我有一个我认为很简单的问题。在我的模型中,我有一个 models.ImageField,看起来像这样:

class CMSDocument(BaseItem):
    thumb = models.ImageField(upload_to= './media/',blank=True)

但我想将其上传到'.media/' + self.pk+ '.png' 我尝试更新模型的保存方法中的字段,但这不起作用,因为调用“保存”时不知道 pk。我还尝试按照此处的建议为 upload_to 添加自定义函数:Django: Any way to change "upload_to" property of FileField without resorting to magic?。但这只会使该领域空无一人。我能做什么?

编辑:我使用 Django 1.6

编辑:我使用了一个不是很好的 post_save 信号:

def video_embed_post_save(sender, instance=False, **kwargs):    
    document = DocumentEmbedType.objects.get(pk=instance.pk)    
    new_thumb = "media/%s.png" % (document.pk,)
    if not document.thumb == new_thumb:
        document.thumb = new_thumb
        document.save()
    ...

【问题讨论】:

  • 一种非常hackish的方法是,在save方法中,获取最后一条记录的id,然后将其加一并用作新的id。
  • hmmm,我实际上最终使用了一个 post_save 信号,这有点像 hack(我检查文件名是否已经正确,如果不是,我更改它并保存模型。这样我不要遇到递归问题)。但我会检查@madzohan 解决方案。

标签: python django


【解决方案1】:

主键由数据库分配,因此您必须等到模型行保存在数据库中。

首先将你的数据分成两个模型,缩略图在子模型上:

from django.db import models

from .fields import CMSImageField


class CMSDocument(models.Model):
    title = models.CharField(max_length=50)


class CMSMediaDocument(CMSDocument):
    thumb = CMSImageField(upload_to='./media/', blank=True)

如您所见,我使用缩略图的自定义字段而不是 ImageField。

然后创建一个fields.py文件,你应该覆盖ImageField继承的FileField类的pre_save函数:

from django.db import models


class CMSImageField(models.ImageField):
    def pre_save(self, model_instance, add):

        file = super(models.FileField, self).pre_save(model_instance, add)

        if file and not file._committed:
            # Commit the file to storage prior to saving the model
            file.save('%s.png' % model_instance.pk, file, save=False)
        return file

因为 CMSMediaDocument 继承自 CMSDocument 类,所以在调用 pre_save 的那一刻,渐进式 PK 已经保存在数据库中,因此您可以从 model_instance 中提取 pk。

我测试了代码,应该可以正常工作。

测试中使用的admin文件:

from django.contrib import admin

from .models import CMSMediaDocument

admin.site.register(CMSMediaDocument)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-07
    • 2020-10-27
    • 2011-02-10
    • 2016-07-12
    • 1970-01-01
    • 2011-06-17
    • 2011-02-02
    • 1970-01-01
    相关资源
    最近更新 更多