2017-08-04 27 views
1

私はDRFバックエンドを使ってファイルをアップロードしています。私の具体的なケースでは、の後にファイル名をアップロードしたいと思うでしょう。その理由は、ユーザーが同じ名前のファイルをアップロードしても、私はそれを独立して処理することができるからです。Djangoが生成した一意のファイル名を複数回アップロードする

views.py

class ImageUploaderView(viewsets.ModelViewSet): 
    renderer_classes = [renderers.JSONRenderer] 
    queryset = ImageUploader.objects.all() 
    serializer_class = ImageUploaderSerializer 
    parser_classes = (MultiPartParser,) 

serializer.py

class ImageUploaderSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = ImageUploader 

models.py

class ImageUploader(models.Model): 
    # name=models.ImageField(upload_to='media') 
    name=models.FileField(upload_to='media') 

私が試しましたモデル定義の後ろにシグナルとフックを入れますが、私はこのファイル名を取得できません。誰かが軽いplを流すことができますか?

UPDATE:私は基本的に達成したいものを詳しく説明してみましょう:

  • User1はフロントエンドで をレンダリングされたエンドポイント "/ API/calculate_interest_rate" リアクトコンポーネント当たります。 「calculate_interest_rate」は DRFで配信され、ユーザーはCSVファイルをアップロードできます。これは "user1.csv"という名前で保存され、ファイルは処理され、表形式になります( Reactでレンダリングされます)。同時に、およびユーザー1に平行で

  • は、User2が同じエンドポイント誤って「/ API/calculate_interest_rate」と 彼は「user1.csv」として彼のファイルを保存し、systemnへのアップロード、それを打ちます。

私は、ファイルの両方の名前を検出して処理できるようにしたいと考えています。同じデフォルトファイル名(例えば、OverwriteStorage()テクニックを使用して)を常に使用することによって、2人以上のユーザーが同じファイル名を使用しているときに混乱を引き起こすでしょう。したがって、私はファイル名をそのまま取得して直ちに処理できる技術を探しています。

+0

なぜセッションを使用しないのですか?例: 'user_ .csv'? –

答えて

1

保存オプションの使用はどうですか?

class OverwriteStorage(FileSystemStorage): 
    def get_available_name(self, name, max_length=None): 
     print("filename", name) 
     #parts = name.split('.') you can separate name and extension. 
     return super().get_available_name(name) 

upload_image = models.ImageField(
    upload_to=[yourpath], 
    default=[defaultname], 
    storage=OverwriteStorage() 
) 
+0

私は上書きしたくない。私の更新を確認してください。 –

+0

更新を読みました。実際には、パスに同じ名前のファイルがある場合、Djangoは同じ名前のファイルを保存しないように自動的にアンダースコアと7つのランダムな文字を入れます。 [source here、get_available_name](https://docs.djangoproject.com/en/1.11/_modules/django/core/files/storage/#Storage.get_available_name)。私はちょうどあなたが保存するときに同じファイル名を持っているときにそれを微調整することを提案しました。 – Jayground

+0

ファイル名を他のファイルと重複させることができないように、ユーザーpk番号を入れないのはなぜですか? user_userのユニークなpk番号のような形式でファイルを保存すると、複数のユーザーが同じファイル名を保存することを心配する必要はありません。 – Jayground

0

私はこの設定を次のようにあなたをお勧め:

1.はその後settings.py

MEDIA_URL = '/media/' 
MEDIA_ROOT = '/path/to/env/projectname/media' 

のファイル中にあなたMEDIA_ROOTMEDIA_URLを変更し、私は変更にあなたを示唆upload_to='mediaupload_to='images/%Y/%m/%dの名前もnameのフィールドの名前をに変更します。

class ImageUploader(models.Model): 
    image = models.FileField(upload_to='images/%Y/%m/%d') 
    # OR 
    # image = models.ImageField(upload_to='images/%Y/%m/%d') 

説明。この設定に従うと、画像がアップロードされている可能性があります(例:/media/images/2017/01/29/yourimage.jpg)。これは、重複ファイルの問題を処理する方法の1つです。

3.しかし、あなたが重複したファイルなしで複数回使用してファイルをアップロードしたい場合は、deconstructibleを使用することができます。

import os, time, uuid 
from django.db import models 
from django.utils.deconstruct import deconstructible 


class ImageUploader(models.Model): 

    @deconstructible 
    class PathAndRename(object): 

     def __init__(self, sub_path): 
      self.path = sub_path 

     def __call__(self, instance, filename): 
      # eg: filename = 'my uploaded file.jpg' 
      ext = filename.split('.')[-1] #eg: '.jpg' 
      uid = uuid.uuid4().hex[:10] #eg: '567ae32f97' 

      # eg: 'my-uploaded-file' 
      new_name = '-'.join(filename.replace('.%s' % ext, '').split()) 

      # eg: 'my-uploaded-file_64c942aa64.jpg' 
      renamed_filename = '%(new_name)s_%(uid)s.%(ext)s' % {'new_name': new_name, 'uid': uid, 'ext': ext} 

      # eg: 'images/2017/01/29/my-uploaded-file_64c942aa64.jpg' 
      return os.path.join(self.path, renamed_filename) 

    image_path = time.strftime('images/%Y/%m/%d') 
    image = models.ImageField(upload_to=PathAndRename(self.image_path)) 
+0

私は上書きしたくない。また、複数のユーザーが同時にアップロードしていると考えてください。正しいファイルを処理できるようにファイル名を取得するにはどうすればよいですか?説明のためにスレッドの更新を確認してください。 –

+0

あなたは特にアップロード機能であなたのビューを更新できますか? –

関連する問題