Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# Imports 

2 

3# from django.conf import settings 

4from django.db.models import FileField 

5import os 

6 

7# Exports 

8 

9__all__ = ( 

10 "handle_file_removal_on_change", 

11 "handle_file_removal_on_delete", 

12) 

13 

14# Receivers 

15 

16 

17def handle_file_removal_on_change(sender, **kwargs): 

18 """Remove the files associated with a model when they have changed on the instance. 

19 

20 .. code-block:: python 

21 

22 from django.db.models.signals import pre_save 

23 from superdjango.storage.receivers import handle_file_removal_on_change 

24 from myapp.models import Document 

25 

26 pre_save.connect( 

27 handle_file_removal_on_change, 

28 Document, 

29 dispatch_uid="myapp_document_handle_file_removal_on_change" 

30 ) 

31 

32 

33 """ 

34 instance = kwargs['instance'] 

35 

36 if not instance.pk: 

37 return False 

38 

39 old_instance = sender.objects.get(pk=instance.pk) 

40 

41 # noinspection PyProtectedMember 

42 for field in instance._meta.get_fields(): 

43 if isinstance(field, FileField): 

44 old_field = getattr(old_instance, field.name) 

45 new_field = getattr(instance, field.name) 

46 

47 if old_field.file != new_field.file: 

48 path = str(old_field.file) 

49 if os.path.isfile(path): 

50 os.remove(path) 

51 

52 

53def handle_file_removal_on_delete(sender, **kwargs): 

54 """Remove any files associated with a model when an instance is deleted. 

55 

56 .. code-block:: python 

57 

58 from django.db.models.signals import post_delete 

59 from superdjango.storage.receivers import handle_file_removal_on_delete 

60 from myapp.models import Document 

61 

62 post_delete.connect( 

63 handle_file_removal_on_delete, 

64 Document, 

65 dispatch_uid="myapp_document_handle_file_removal_on_delete" 

66 ) 

67 

68 

69 """ 

70 # A management command (which would require specifying the models for which file uploads are included) or a signal 

71 # handler appears to be the only way to deal with files orphaned by a model delete. 

72 # https://stackoverflow.com/a/16041527/241720 

73 instance = kwargs['instance'] 

74 

75 # noinspection PyProtectedMember 

76 for field in instance._meta.get_fields(): 

77 if isinstance(field, FileField): 

78 _field = getattr(instance, field.name) 

79 path = str(_field.file) 

80 if path and os.path.isfile(path): 

81 os.remove(path)