django - 删除和恢复文件和级联文件夹 Django
问题描述
我是 django 的新手,我正在做一个类似于 google Drive 的项目。
- 我希望当我软删除文件夹或文件时,它应该出现在垃圾箱中(只有父文件夹,以防它有子文件夹),但不应该在媒体根文件夹中删除
- 我希望能够恢复文件夹(及其子文件夹,如果有的话)或文件
- 我还希望能够永久删除垃圾箱中的文件或文件夹
这是我写的代码
import os
import safedelete
from django.db import models
from safedelete.models import SafeDeleteModel
from safedelete.models import SOFT_DELETE_CASCADE
from safedelete.models import HARD_DELETE
from documentation.manager import *
from datetime import datetime
from django.urls import reverse
from django.utils.text import slugify
from django.db.models.signals import post_delete, pre_save
from django.dispatch import receiver
from account.models import CustomUser
from program.models import Activity
#a model to create the folder
class Folder(SafeDeleteModel):
_safedelete_policy = SOFT_DELETE_CASCADE
objects = MyModelManager()
creator = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null = True)
activity_name = models.ForeignKey(Activity, on_delete=models.CASCADE, blank = True, null=True)
name = models.CharField(max_length=64)
parent = models.ForeignKey('self', on_delete=models.CASCADE, blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
path = models.CharField(max_length=2048, blank=True)
slug = models.SlugField(blank=True)
def __str__(self):
return self.name
def get_absolute_url(self):
kwargs = {'slug' : self.slug}
return reverse('', kwargs=kwargs)
def get_path(self):
if self.parent:
yield from self.parent.get_path()
yield self.name
def complete_get_path(self):
return "/".join(self.get_path())
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
self.path = self.complete_get_path()
return super().save(*args, **kwargs)
class Meta:
unique_together = [['parent', 'name']]
ordering = ('name',)
class Uploads(SafeDeleteModel):
_safedelete_policy = SOFT_DELETE_CASCADE
objects = MyModelManager()
Images = 3
Video = 2
Documents = 1
CHOICES = (
(Images, 'Images'),
(Video, 'Video'),
(Documents, 'Documents')
)
activity_name = models.ForeignKey(Activity, on_delete=models.CASCADE, blank = True, null=True)
doc_type = models.PositiveSmallIntegerField(choices=CHOICES, blank=True, null=False)
doc_name = models.CharField(max_length=50)
uploader_name = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
folder = models.ForeignKey(Folder, on_delete=models.CASCADE, blank = True, null=True)
dete_uploaded = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
upload_path = models.FileField(upload_to='%Y/%m/%d', default = "files/", verbose_name = "Choose File", blank = False)
def __str__(self):
return self.doc_name
class Meta:
verbose_name_plural = "Files"
# These two auto-delete files from filesystem when they are unneeded:
@receiver(models.signals.post_delete, sender=Uploads)
def auto_delete_file_on_delete(sender, instance, **kwargs):
"""
Deletes file from filesystem
when corresponding `Uploads` object is deleted.
"""
if instance.upload_path:
if os.path.isfile(instance.upload_path.path):
os.remove(instance.upload_path.path)
@receiver(models.signals.pre_save, sender=Uploads)
def auto_delete_file_on_change(sender, instance, **kwargs):
"""
Deletes old file from filesystem
when corresponding `Uploads` object is updated
with new file.
"""
if not instance.pk:
return False
try:
old_file = Uploads.objects.get(pk=instance.pk).upload_path
except Uploads.DoesNotExist:
return False
new_file = instance.upload_path
if not old_file == new_file:
if os.path.isfile(old_file.path):
os.remove(old_file.path)
目前发生的事情是
当我软删除文件时,它出现在垃圾箱中,但它也被永久删除在媒体根文件夹中
当我软删除有子文件夹时,它们会单独显示在垃圾箱中
这是垃圾箱视图的代码
from rest_framework.views import APIView
from rest_framework.parsers import FileUploadParser
from rest_framework.permissions import IsAuthenticated
from rest_framework import status
from safedelete.models import HARD_DELETE
from django.http import Http404
from users.serializer import UserSerializer
from account.models import CustomUser
from documentation.models import *
from documentation.serializers import *
from rest_framework.response import Response
# Create your views here.
''' Trash Zone '''
class UserFolderFileTrashView(APIView):
serializer_class = UserSerializer
permission_classes = [IsAuthenticated]
def get_object(self, pk): #get deleted folder
try:
return Folder.objects.deleted_only().filter( creator_id = pk)
except Folder.DoesNotExist:
raise Http404
def get_objects(self, pk): #get deleted files belonging to a folder
try:
return Uploads.objects.deleted_only().filter( folder__id__isnull = False , uploader_name_id = pk)
except Uploads.DoesNotExist:
raise Http404
def get_objectss(self, pk): # get deleted files in the base activity
try:
return Uploads.objects.deleted_only().filter( activity_name__id__isnull = False , uploader_name_id = pk)
except Uploads.DoesNotExist:
raise Http404
def get(self, request,*args, **kwargs):
serializer = {}
folder = self.get_object(self.kwargs.get('pk', ''))
filee = self.get_objects(self.kwargs.get('pk', ''))
filee2 = self.get_objectss(self.kwargs.get('pk', ''))
serializer['folders'] = FolderSerializer(folder, many=True).data
serializer['files_level1'] = FileSerializer(filee2, many=True).data
serializer['files_level2'] = FileSerializer(filee, many=True).data
return Response(serializer)
''' Undelete / Delete File and folders from Trash '''
#Trash Files update view
class TrashFilesUpdateView(APIView):
parser_class = (FileUploadParser,)
serializer_class = FileSerializer
permission_classes = [IsAuthenticated]
def get_object(self, pk):
try:
return Uploads.objects.get(pk=pk)
except Uploads.DoesNotExist:
raise Http404
def get(self, request, *args, **kwargs):
filee = self.get_object(self.kwargs.get('file_id', ''))
serializer = FileSerializer(filee)
return Response(serializer.data)
def put(self, request, *args, **kwargs):
filee = self.get_object(self.kwargs.get('file_id', ''))
filee.undelete()
serializer = self.serializer_class(filee, data=request.data)
valid = serializer.is_valid(raise_exception=True)
if valid:
status_code = status.HTTP_201_CREATED
serializer.save()
return Response(serializer.data, status=status_code)
def delete(self, request, *args, **kwargs):
filee = self.get_object(self.kwargs.get('file_id', ''))
filee.delete(force_policy= HARD_DELETE, **kwargs)
return Response(status=status.HTTP_204_NO_CONTENT)
#Trash Folders update view
class TrashFoldersUpdateView(APIView):
serializer_class = FolderSerializer
permission_classes = [IsAuthenticated]
def get_object(self, pk):
try:
return Folder.objects.get(pk=pk)
except Folder.DoesNotExist:
raise Http404
def get(self, request, *args, **kwargs):
folder = self.get_object(self.kwargs.get('folder_id', ''))
serializer = FolderSerializer(folder)
return Response(serializer.data)
def put(self, request, *args, **kwargs):
folder = self.get_object(self.kwargs.get('folder_id', ''))
folder.undelete()
serializer = self.serializer_class(folder, data=request.data)
valid = serializer.is_valid(raise_exception=True)
if valid:
status_code = status.HTTP_201_CREATED
serializer.save()
return Response(serializer.data, status=status_code)
def delete(self, request, *args, **kwargs):
folder = self.get_object(self.kwargs.get('folder_id', ''))
folder.delete(force_policy= HARD_DELETE, **kwargs)
return Response(status=status.HTTP_204_NO_CONTENT)
解决方案
推荐阅读
- javascript - 失败:TypeError:__WEBPACK_IMPORTED_MODULE_2_react___default.a.createContext 即使在更新后也不是函数
- python - 如何使用python在不同的变量中迭代和赋值
- javascript - 我需要更改什么才能在 JS 中调用我的函数?
- c# - 从 HttpWebResponse 获取请求的响应头
- javascript - 使用来自 golang 的数据将元素添加到 html 页面
- r - 尝试使用 R 中 k 的最佳值从交叉验证的结果中创建混淆矩阵
- c# - 按 Z 或 X 时崩溃
- python - python sql insert语句在数据库中插入带引号的值
- azure - 如何检查内部应用服务环境中托管的内部应用服务的可用性
- python - Django:“字段通过尚未安装的模型指定多对多关系”错误