Скачать файл через Django-Filer вместо Redirect - PullRequest
0 голосов
/ 29 ноября 2018

Я делаю систему обслуживания файлов, которая организует различные файлы на основе категорий.Когда пользователь находит нужный файл, он нажимает кнопку загрузки, и он загружает его.Это разные типы файлов pdf, ai, video и т. Д. Я использовал атрибут загрузки в HTML, и он работал находить локально, но потом обнаружил, что он не работает, когда я отправил его на хостинг.

Я прочитал 20 различных постов об использовании Content-Dispostion, но у меня возникли проблемы даже с этой точкой зрения.У меня совсем немного работы, но ниже я попытаюсь получить доступ к файлу, чтобы иметь возможность отправить его обратно пользователю.Честно говоря, я просто не уверен, куда идти отсюда.Я просто хочу, чтобы использование могло нажимать кнопку, и файл django-filer загружается

Дайте мне знать, если мне нужно включить что-нибудь еще.

def asset_detail_view(request, slug, *args, **kwargs):
    obj = get_object_or_404(Asset.objects.prefetch_related('file_set'), slug=slug)

    context = {
        'object': obj,
    }
    return render(request, 'detail_view.html', context)

def search(request):
    queryset = Asset.objects.prefetch_related('file_set').all()
    filter_set = AssetFilter(request.GET, queryset=queryset)
    return render(request, 'asset_filter_view.html', {'filter': filter_set})

def download(request, slug):
    download = File.objects.filter( asset__slug=slug ).first()
    file = FilerFile.objects.filter(id=download.file_id)
    for attr, value in file.__dict__.items():
        print(attr, value)


    return HttpResponse("Test")

models

class Asset(models.Model):
    name = models.CharField(max_length=50, blank=False)
    slug = models.SlugField()
    summary = models.TextField(max_length=120, blank=True, default='Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sapiente esse necessitatibus neque sequi doloribus.')
    asset_type = models.ForeignKey(File_Type, blank=False)
    description = PlaceholderField('asset_description')
    asset_category = models.ManyToManyField(Asset_Category, blank=True)
    tag = models.ManyToManyField(Tag, blank=True)
    product_category = models.ManyToManyField(Category, blank=True)
    product_series = models.ManyToManyField(Series, blank=True)
    product_line = models.ManyToManyField(Line, blank=True)
    product = models.ManyToManyField(Product, blank=True)
    url = models.CharField(max_length=250, blank=True, verbose_name='Video URL')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    is_active = models.BooleanField(default=True)


    def get_absolute_url(self):
        return reverse("assets:asset_detail", kwargs={"slug": self.slug})

    def __str__(self):
        return self.name

class File(models.Model):
    name = models.CharField(max_length=50, blank=False)
    description = models.TextField(blank=True)
    image = FilerImageField(default=28, null=True, blank=True, related_name="image_file", verbose_name="Thumbnail")
    file = FilerFileField(null=True, blank=True, related_name="file_file")
    asset = models.ForeignKey(Asset, blank=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    is_active = models.BooleanField(default=True)

    def __str__(self):
        return self.name

1 Ответ

0 голосов
/ 30 ноября 2018

Собираюсь ответить на мой собственный вопрос.Я не уверен, что это лучший способ, но он сработал для меня.Вместо того, чтобы создавать новый URL для загрузки изображений, я создал условные операторы внутри asset_detail_view, чтобы перехватить форму, которая была отправлена ​​через шаблон.Я думаю, что это то, что делают большинство других ответов, как это, но это не очень хорошо объяснено (по моему мнению), поэтому я был очень смущен, когда другие размещали эту логику.Это нарушило процесс локально, потому что он должен открыть URL-адрес, а urllib не знает, как обрабатывать локальные пути.

Шаблон HTML:

<div>
      <form>
            <input type="text" name="path" value="{{ **object url** }}" hidden>
            <input class="btn btn-primary" type="submit" value="Download">
      </form>
</div>

Здесь вам нужно найти способчтобы получить URL файла, я использовал django-filer, так что это было легко.Я удалил дополнительные вызовы, которые я должен был сделать, чтобы получить его, потому что это свойственно моему коду и не будет работать для других.После отправки он был отправлен в то же представление, в котором он уже находился, но теперь к нему была прикреплена переменная path.

views.py

from urllib.request import Request, urlopen

def asset_detail_view(request, slug, *args, **kwargs):
    obj = get_object_or_404(Asset.objects.prefetch_related('file_set'), slug=slug)

    context = {
        'object': obj,
    }

    if request.GET:
        query = request.GET
        filepath = query.get('path','0')
        filename = os.path.basename(os.path.normpath(filepath))
        hdr = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
       'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
       'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
       'Accept-Encoding': 'none',
       'Accept-Language': 'en-US,en;q=0.8',
       'Connection': 'keep-alive'}

        req = Request(filepath, headers=hdr)

        with urlopen(req) as f:
            response = HttpResponse(f.read(), content_type='application/octet-stream')
            response['Content-Type'] = 'application/octet-stream'
            response['Content-Disposition'] = 'attachment; filename={0}'.format(filename)
            print (response['Content-Disposition'])
            return response


    return render(request, 'detail_view.html', context)

переменная hdr была странной для меняи мне пришлось покопаться, чтобы найти его.Из того, что я понимаю, вы по существу убеждаете сервер, что вы браузер, а не блок кода, пытающийся получить доступ к серверу.Вы можете просто скопировать и вставить это.

Если кому-то еще есть что добавить, или есть более простой способ справиться с этим, не стесняйтесь комментировать или отвечать.Надеюсь, это поможет кому-то еще!

...