2017-12-11 1 views
-1

스코어 카드라는 모델. 스코어 카드에는 고유 한 CharField name이 있습니다. .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 인 경우 무언가해야합니까?

참고 : 파일 이름이 불량 할 수도 있음을 알고 있습니다. 나는 아마 그 부분을 slugifying 또는 나중에 무언가에 의해 고칠 것이다.

+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.ModelAdmin에 정의했지만 완전히 이벤트 체인을 이해하지 못한다고 생각합니다.

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) 
관련 문제