我有一个上传信息中心,上传表单和显示文件的表格。在最后一列中是诸如删除之类的操作。但是当我按下删除它会删除数据库中的模型,但文件仍然在文件夹中。我想要从这个文件夹中删除文件,如果我可以将删除的文件移动到另一个类似回收站的目录,那么甚至更好,这样管理员即使被上传的用户删除也可以查看文件。 (用户基数低于10,因此可以很简单)
除此之外,我很奇怪是否有办法在pre_delete中包含某种确认警告框,这样当他们按下删除时它会在对话框中要求确认。
这是我到目前为止的代码:
我的视图一个用于仪表板,另一个用于删除:
@login_required(login_url='/dashboard-login/')
def dashboard(request):
current_user = request.user
current_client = request.user.client
files = ClientUpload.objects.filter(client=current_client)
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
dz_files = request.FILES.getlist('file_upload')
for f in dz_files:
new_file = ClientUpload(client=current_client, file_upload=f)
new_file.save()
logger = logging.getLogger(__name__)
logger.info("File uploaded from " + current_client.company)
else:
logger = logging.getLogger(__name__)
logger.warning("Upload Failed")
return HttpResponseRedirect(reverse('dashboard'))
else:
form = UploadFileForm()
data = {'form': form, 'client': current_client, 'files': files}
return render_to_response('dashboard.html', data, context_instance=RequestContext(request))
def dashboard_delete(request, upload_id):
current_user = request.user
current_client = request.user.client
form = UploadFileForm()
p = ClientUpload.objects.get(pk=upload_id)
p.delete()
files = ClientUpload.objects.filter(client=current_client)
data = {'form': form, 'client': current_client, 'files': files}
return render_to_response('dashboard.html', data, context_instance=RequestContext(request))
我的模特和信号:
@python_2_unicode_compatible
class ClientUpload(models.Model):
client = models.ForeignKey(Client)
created_at = models.DateTimeField(auto_now_add=True)
file_upload = models.FileField(upload_to=generate_filename)
def __str__(self):
return self.client.company
class Meta:
verbose_name_plural = _("Client Uploads")
verbose_name = _("Client Upload")
@receiver(post_delete, sender=ClientUpload)
def clientupload_delete(sender, instance, **kwargs):
if instance.file:
# Pass false so FileField doesn't save the model.
instance.file.delete(False)
else:
# log failure
我的文件列表模板:
{% load i18n %}
{% load staticfiles %}
{% load sasite_filters %}
<table class="table">
<tr>
<th>{% blocktrans %}Filename{% endblocktrans %}</th>
<th>{% blocktrans %}Size (Bytes){% endblocktrans %}</th>
<th>{% blocktrans %}Upload Time{% endblocktrans %}</th>
<th>{% blocktrans %}Actions{% endblocktrans %}</th>
</tr>
{% for file in files %}
{% with uploaded_file=file.file_upload %}
<tr>
<th><a href='{{ uploaded_file.url }}'>{{ uploaded_file.name|pathend}}</a></th>
<th>{{ uploaded_file.size }}</th>
<th>{{ file.created_at }}</th>
<th><a href="{% url 'dashboard-delete' file.id %}">Delete</a></th>
{% endwith %}
{% endfor %}
</tr>
</table>
我的信息中心的网址已删除:
url(r'^dashboard/delete/(?P<upload_id>\d+)$', views.dashboard_delete, name='dashboard-delete'),
这是否需要我确保删除文件?我是否正确使用了信号?我错过了一步吗?我只想确定,因为我试图添加信号,我希望将文件复制到&#34;回收站&#34;在我擦除之前的目录,此时它不需要模型,只能是目录中的文件。但无论如何,在我完成删除模型之前,我希望将其从upload_to目录中删除并移至另一个目录。
前或后删除正确的在线使用?并删除确认框?我应该使用pre_delete还是应该使用JavaScript进行确认对话?我不确定。任何示例/建议都有很大的帮助。
提前致谢。
编辑:
我不完全确定发布/预删除信号是如何工作的,但它似乎适用于删除文件。但我不确定它是否也能用于移动文件。使用FileStorageSystem或自定义文件存储会更好吗?基本上我想在删除之前将文件移动到另一个目录。有人能举例说明我在post_delete中做过的信号吗?如果FileStorage有更好的方法,那么这个例子将是一个很大的帮助,因为我不能为我的生活找到如何实现这一目标。
我的第二个问题是添加确认删除,我认为通过JS / jQuery可以更好地实现?有人告诉我,如果我使用DeleteView CBV会有删除确认,但是我无法让它工作。
再次感谢。
EDIT2:
以下是我在删除文件之前尝试移动文件的情况,请告诉我,如果我搞砸了它,它似乎有用,但我不太确定,因为我从来没有真的之前使用过这样的信号。
@receiver(post_delete, sender=ClientUpload)
def clientupload_postdelete(sender, instance, **kwargs):
if instance.file:
with f as open(settings.MEDIA_ROOT + '/uploads/Recycle', 'w+'):
f.write(instance.file)
f.close()
# Pass false so FileField doesn't save the model.
instance.file.delete(False)
else:
logger = logging.getLogger(__name__)
logger.Warn("Failed to delete %s" % instance.file)
答案 0 :(得分:0)
我找到的解决方案是像这样使用shutil.move()
:
@receiver(post_delete, sender=ClientUpload)
def clientupload_postdelete(sender, instance, **kwargs):
if instance.file_upload:
filename = os.path.basename(instance.file_upload.path)
client = instance.client.company
folder_path = os.path.join(settings.MEDIA_ROOT, 'uploads/Recycle/', client + '/')
if not os.path.exists(folder_path):
os.makedirs(folder_path)
if os.path.exists(os.path.join(folder_path, filename)):
filename = append_id(filename)
shutil.move(instance.file_upload.path, os.path.join(folder_path, filename))
logger = logging.getLogger(__name__)
logger.info("File %s moved to %s" % (filename, settings.MEDIA_ROOT + '/uploads/Recycle/' + client + '/'))
# Pass False so FileField doesn't save the model.
instance.file_upload.delete(False)
else:
logger = logging.getLogger(__name__)
logger.warning("Failed to find file for copying to %s." % (settings.MEDIA_ROOT + '/uploads/Recycle/'))