2017-12-11 6 views
-1

スコアカードという名前のモデル。スコアカードには、name CharFieldがあります。 .csvファイルをメディアフォルダに保存します。私はpre_save信号を作成しようとしています(変更されている可能性があるため)古い名前を取得し、削除するメディアの.csvファイルを確認します。Djangoのpre_saveシグナルには他に必要ですか?

以下の信号コードをコメントアウトして新しいインスタンスを作成すると、必要に応じて.csvが自分のメディアフォルダに作成されます。

以下の信号をコメント解除すると、.csvファイルは、既存のインスタンスを編集して保存するときにのみ出力されますが、作成時には出力されません。

@receiver(pre_save, sender=Scorecard) 
def file_delete_handler(sender, instance, **kwargs): 
    print('INSTANCE ID:', instance.pk) 
    if instance.pk is not None: 
     old = Scorecard.objects.get(pk=instance.pk) 
     print(old.name) 
     file_path = os.path.join(MEDIA_ROOT, ''.join([old.name, '.csv'])) 
     if os.path.exists(file_path): 
      os.remove(file_path) 

これは、これがelse文なしのif文であると考えられますか?私はelse: returnelse: passを試しました。私は何を理解していないのですか?インスタンスがNoneの場合は、何かする予定ですか?

注:ファイル名が貧弱なため、名前の由来はわかりません。私はおそらく、その部分を後で修正するつもりです。

+0

...これは、あなたが明示的に言いましたように、既存のものを編集するときだけです*、確かに? –

+0

シグナルを扱うときにinstance.pkがNoneのときに何をすべきかを明示的に指定しなければならないのですか、それとも.save()に続行されることになっていますか? – Jarad

+0

私は本当にここであなたが望むものを理解していません。それが誰もいないときと同じでないときに同じことが起こるようにするには、ifステートメントを持たないでください。 –

答えて

0

これは動作します:

@receiver(pre_save, sender=Scorecard) 
def file_delete_handler(sender, instance, **kwargs): 
    try: 
     old = Scorecard.objects.get(pk=instance.pk) 
     if old.name != instance.name: 
      # name has been changed 
      file_path = os.path.join(MEDIA_ROOT, ''.join([old.name, '.csv'])) 
      if os.path.exists(file_path): 
       os.remove(file_path) 
    except: 
     pass 

ないこの:

@receiver(pre_save, sender=Scorecard) 
def file_delete_handler(sender, instance, **kwargs): 
    print('INSTANCE ID:', instance.pk) 
    if instance.pk is not None: 
     old = Scorecard.objects.get(pk=instance.pk) 
     print(old.name) 
     file_path = os.path.join(MEDIA_ROOT, ''.join([old.name, '.csv'])) 
     print(file_path) 
     if os.path.exists(file_path): 
      print('Deleting: {}'.format(file_path)) 
      os.remove(file_path) 
    else: 
     print('Instance equals None, do nothing!') 

私が解決しようとしていた問題だった:私は最終的にはAPIからデータをダウンロードセロリのタスクを持って、そしてパンダがいることを要しますデータはto_csv(...)を使用してデータを/media/フォルダに保存します。私がしようとしていたのは、誰かが既存のオブジェクトを編集して名前を変更した場合、名前が "name" .csvであるため/ media /内の古いファイルを削除することでした。

pre_save、セロリの遅延の組み合わせと私がadmin.ModelAdminsave_modelを定義したと思うが、まだイベントのチェーンを完全に理解していない。

class ScorecardAdmin(admin.ModelAdmin): 
    ... 
     result = get_report.delay(name, start, end, type) 
     set_task_status.delay(result.task_id) 
     obj.task_id = result.task_id 
    super().save_model(request, obj, form, change) 
関連する問題