如何重写模型的保存方法以更改文件字段名称?

时间:2019-07-05 11:23:48

标签: python django django-models django-forms

我的django应用程序中有一个ModelForm,它允许用户上传文件并将其存储到AWS Storage S3。我想做的就是将文件从其原始名称重命名为字段timestamp的名称。到目前为止,我已经尝试覆盖模型的save方法。这是我的代码:

models.py

 from converter.storage_backends import CsvStorage
 from django.db import models
 from django.utils import timezone
 import time



 class CSVUpload(models.Model):
   csv_file = models.FileField(storage=CsvStorage())
   timestamp = models.CharField(max_length=1000, default= time.time())

   def __str__(self):
      return self.csv_file


   def save(self, *args, **kwargs):
    self.csv_file.name = self.timestamp + ".csv"
    super(CSVUpload, self).save(*args, **kwargs)

forms.py

  from django import forms
  from .models import CSVUpload
  import time

  class CsvForm(forms.ModelForm):

  csv_file = forms.FileField(widget=forms.FileInput(
      attrs= {
        'class': 'form-group',
      }
   ))

  timestamp = forms.CharField(initial = time.time())

  class Meta:
    model = CSVUpload
    fields = ('csv_file', 'timestamp',)

  def save(self):
    csvfile = super(CsvForm, self).save()
    return csvfile

我的观点:

 def uploadcsv(request):
   if request.method == 'POST':
      form = CsvForm(request.POST, request.FILES)
      if form.is_valid():
        return redirect(about)
   else:
    form = CsvForm()
    return render(request, 'myapp/uploadcsv.html',{'form': form})

编辑

storage_backends.py

  from storages.backends.s3boto3 import S3Boto3Storage 
  from django.conf import settings

  class CsvStorage(S3Boto3Storage):
     location = settings.AWS_CSV_LOCATION    
     file_overwrite = False

尽管如此,当我上传文件时,它并未到达存储桶中。我不确定出什么问题了,但我怀疑这取决于保存方法。有人可以帮助我了解如何解决此问题吗?感谢您的帮助

2 个答案:

答案 0 :(得分:1)

Django具有FileField的内置参数,该参数接受一个用于指定对象文件名的函数。该参数称为upload_to,您可以从here中找到详细信息。

答案 1 :(得分:0)

Django的FileField [Django-doc]支持使用upload_to parameter [Django-doc]指定上传文件名:

  

(..)

     

upload_to也可以是可调用的,例如函数。这将成为;这将是   调用以获取上载路径,包括文件名。这个   callable必须接受两个参数并返回Unix样式的路径(带有   正斜杠)传递给存储系统。 (..)

因此我们可以通过以下方式实现此目标:

class CSVUpload(models.Model):

    def get_csv_name(self, filename):
        return '{}.csv'.format(self.timestamp)

    csv_file = models.FileField(upload_to=get_csv_name, storage=CsvStorage())
    timestamp = models.CharField(max_length=1000, default= time.time())

    def __str__(self):
        return self.csv_file