Как загрузить загруженный каталог в виде zip-файла из администратора django?

Я загрузил каталог, используя django и JavaScript. Теперь я пытаюсь загрузить этот каталог из администратора django. Для этого я перешел по этой ссылке нажмите здесь. Когда я загрузил каталог в django, администратор создал следующую таблицу. Имя файла указывает имя загруженной папки.

введите здесь описание изображения

Если я нажму на имя файла, он покажет мне следующую ошибку. Я хочу загрузить этот каталог в виде zip-файла из администратора django. Кто-нибудь может помочь мне с этим?

введите здесь описание изображения

Вот мой model.py:

class Prearchive(models.Model):
    file = models.FileField(upload_to='media/', null=True) 
    file_name = models.CharField(max_length=500,primary_key=True)    
    file_id = models.ForeignKey(CreateScan, on_delete=models.CASCADE,default=1) 

    def _str_(self):
        return self.file_name 

admin.py:

from django.contrib import admin
from .models import CreateScan, Prearchive

# Register your models here.

class PrearchiveAdmin(admin.ModelAdmin):
    model=Prearchive
    list_display = ('file_name','file_id','file_link')
    def file_link(self, obj):
        if obj.file:
            return "<a href='%s' download>Download</a>" % (obj.file.url,)
        else:
            return "No attachment"
    file_link.allow_tags = True
    file_link.short_description = 'File Download'

admin.site.register(Prearchive , PrearchiveAdmin)

view.py:

@login_required
def downloadScanView(request,url):
    print('url',url)
    response = HttpResponse(content_type='application/zip')
    file_path = os.path.join(settings.MEDIA_ROOT, url)
    zip_download = ZipFile(response, 'w',ZIP_DEFLATED)
    if os.path.exists(file_path):
        for root, dir, files in os.walk(file_path):
            print('r = ',root)
            for file in files:
                zip_download.write(os.path.join(root,file))
        response['Content-Disposition'] = 'attachment; filename={}'.format(os.path.basename(url)+'.zip')
        return response

person reasm001    schedule 28.06.2020    source источник
comment
Задача Celery заархивировать эти файлы в папку tmp, затем отправить, когда файлы будут готовы, уведомив об этом по электронной почте, срок действия которого истекает через 24 часа, а затем удалить эти временные заархивированные файлы.   -  person frozenOne    schedule 28.06.2020
comment
Спасибо за ваш ответ. Проблема в том, что когда я перехожу по этому URL-адресу: 127.0.0.1:8080/media/iit_0001_9_Unknown_aser4, У меня есть это «Индексы каталогов здесь не разрешены». ошибка. Я даже не вижу файлы внутри каталога. Как я могу получить файлы внутри папки, используя эту ссылку на папку?   -  person reasm001    schedule 28.06.2020
comment
Вы не можете перейти по этому URL-адресу, потому что он не определен в django, и основное предположение состоит в том, что если вы отправляете файлы для загрузки, вы делаете это с помощью s3 или серверной части хранилища мультимедиа. Вы определили корень носителя в вашей папке settings.py?   -  person frozenOne    schedule 28.06.2020
comment
Я использую серверную часть хранилища мультимедиа и определил ее в settings.py. Это в моем файле settings.py: MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media'). И я также установил это (если settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)) в моем url.py. Я изменил свой вопрос и прикрепил туда код просмотра загрузки. Не могли бы вы объяснить мне немного об этом? Заранее спасибо.   -  person reasm001    schedule 28.06.2020
comment
Я не уверен, почему это происходит, но URL-адрес, который я получаю, выглядит примерно так: /media/folder_name. Мой параметр .MEDIA_ROOT: /User/project/media. Поэтому, когда я пытаюсь использовать os.path.join(), он возвращает тот же путь, что и URL-адрес (/media/folder_name). Он не присоединяется к URL-адресу с путем MEDIA_ROOT.   -  person reasm001    schedule 28.06.2020
comment
Привет, сейчас работает. Я попытался соединить абсолютный путь с MEDIA_ROOT. Вот почему он не мог правильно найти путь к файлу. Я взял имя базового каталога из URL-адреса и присоединился к MEDIA_ROOT. Теперь это работает. Надеюсь, я делаю это правильно. Кстати, большое спасибо за ваше предложение.   -  person reasm001    schedule 28.06.2020
comment
Тогда все работает как задумано? Если не дайте мне знать, что не так, я немного глуп.   -  person frozenOne    schedule 28.06.2020
comment
На самом деле он работает только тогда, когда я вызываю downloadScanView из шаблона. Я не могу загрузить его из панели администратора django. Не могли бы вы дать мне предложение для этого?   -  person reasm001    schedule 28.06.2020
comment
Да, вам также нужно использовать MEDIA_ROOT в функции file_link. Это поможет: stackoverflow.com /вопросы/50764746/   -  person frozenOne    schedule 28.06.2020
comment
Я использовал его в file_link. Неудачно. Он просто показывает текст '‹a href='/users/project_name/media/folder_name' download›Download‹/a›» вместо создания какой-либо ссылки.   -  person reasm001    schedule 28.06.2020


Ответы (1)


Создайте представление для загрузки файла и добавьте запись urls.py для /media в это представление.

просмотры.py

def filedownload(request, filename):
    zf = zipfile.ZipFile('download.zip', 'w', zipfile.ZIP_DEFLATED)
    zf.write("media/" + filename)
    response = HttpResponse(zf, content_type='application/force-download')
    response['Content-Disposition'] = 'attachment; filename="download.zip"'
    return response

Основной urls.py

path('media/', include('your_app.urls')

URL-адрес приложения.py

path("<filename>/", views.filezip, name="filedownload")
person 55abhilash    schedule 28.06.2020
comment
Можем ли мы сделать это таким образом? Где на самом деле происходит застегивание? Если это происходит на стороне сервера, для обычно больших файлов не будет ли это блокировать поток? - person frozenOne; 28.06.2020
comment
Хорошо, я полностью пропустил, что вы хотите заархивировать файлы. - person 55abhilash; 28.06.2020