【问题标题】:Django FileField on Model, Delete File When Deleting Model and Confirmation模型上的Django FileField,删除模型时删除文件并确认
【发布时间】:2015-08-05 13:19:29
【问题描述】:

我有一个上传仪表板,其中包含一个上传表单和一个显示文件的表格。最后一列是删除等操作。但是当我按下删除它会删除数据库中的模型,但文件仍在文件夹中。我也想从这个文件夹中删除文件,如果我可以将删除的文件移动到另一个目录(比如回收站),这样管理员就可以看到文件,即使它们被上传文件的用户删除。 (用户群在 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'),

这就是我需要做的所有事情来确保文件被删除吗?我是否正确使用了信号?我错过了一步吗?我只是想确定一下,因为我正在尝试添加信号,即我希望在删除文件之前将文件复制到“回收站”目录,此时它不需要模型,可以成为目录中的一个文件。但无论如何,在我完成删除模型之前,我希望它从它的 upload_to 目录中删除并移动到另一个目录。

是删除前删除还是删除后要在此处使用正确的删除?而对于删除的确认框?我应该使用 pre_delete 还是应该使用 JavaScript 进行确认对话?我不确定。任何示例/建议都会有很大帮助。

提前致谢。

【问题讨论】:

  • 您的第一种方法应该适用于此更改:instance.file_upload.delete(False)

标签: python django


【解决方案1】:

有一个错字可以正常工作:

@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/'))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-09
    • 2014-01-09
    • 1970-01-01
    • 2011-04-18
    • 2011-09-16
    • 2017-12-31
    相关资源
    最近更新 更多