Скачивание файлов с сайта

    blazer |   09.10.2019 |   16:47:59 |   Django |

В этой статье я расскажу и покажу, как делал скачивание файла прайс листа с любой страницы сайта без применения js, ajax и прочего.

Задача была такая. Нужно загружать xls файл прайс листа на сайт с админки, который имеет постоянное неизменяемое имя и возможность скачать его с любой страницы сайта без перезагрузки страницы.

А так же вывести его размер и количество загрузок.

Пишем простенькую модель для хранения прайс-листа.

class PriceList(models.Model):
    '''Модель прайс листа'''
    title = models.CharField(max_length=250, verbose_name='Заголовок')
    file = models.FileField(upload_to='price_list/%y/%m/%d/', verbose_name='Файл')
    counter = models.PositiveIntegerField(default=0, verbose_name='Кол-во загрузок')
    is_active = models.BooleanField(default=True, verbose_name='Модерация')
    created = models.DateTimeField(auto_now_add=True, verbose_name='Создан')
    updated = models.DateTimeField(auto_now=True, verbose_name='Изменен')

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'Прайс лист'
        verbose_name_plural = 'Прайс листы'
        ordering = ['-created']

тут по сути даже ничего объяснять не нужно т.к. все поля подписаны и в конце статьи будет видео на эту тему, где я кратко объяснял все.

По сколько ссылки на загрузку должны выводиться на всем сайте т.е. быть сквозными, то я решил сделать это через context_processors.

В файле context_processors.py моего приложения shop я сделал такой метод

def price_list(request):
    '''Прайс лист'''
    price = PriceList.objects.filter(is_active=True)
    return {'price_list': price}

Из модели PriceList по фильтру получаю объекты отфильтрованные по полю is_active т.е. промодерированные и возвращаю словарь в котором ключь price_list и его значение price.

Переходим в settings.py и в список контекстных процессоров я добавил этот контекстный процессор. Если не добавить, то ничего работать не будет!

'shop.context_processors.price_list',

Далее в shop/views.py я сделал такую вьюху

def price_list_count(request, pk):
    '''Счетчик клика по ссылке скачать прайс лист.'''
    # try:
    #     price = get_object_or_404(PriceList, is_active=True)
    # except MultipleObjectsReturned:
    #     return HttpResponse('Вы выбрали более одного файла')
    price = PriceList.objects.get(pk=pk)
    price.counter += 1
    price.save()
    return redirect(price.file.url)

Почему часть кода закомментирована я объяснял в видео, которое будет в самом низу статьи. В двух словах, то тут можно управлять количеством файлов то ли выводить их все списком или же только один. Более подробней я объяснил и показал в видео. Кстатии пока писал это пришла мысль, что было бы не плохо тут еще сделать проверку, чтоб код был в нормальном виде)))

В urls.py сделал ссылку

path('price/<pk>/', price_list_count, name='price_list_count'),

И в шаблоне base.html это все отобразил так.

<li>
   {% if price_list %}
	{% for p in price_list %}
	    <a href="{% url 'shop:price_list_count' p.pk %}">
		<img class="right-5" src="{% static 'shop/img/icon/xls.png' %}"
		   alt="#" style="width: 16px; height: 11px;">Скачать прайс в xls &nbsp;
				Размер: {{ p.file.size|filesizeformat }} | Скачан: 
                                  <span>
					class="badge" style="margin-top: 7px;">{{ p.counter}}
                                  </span>раз
	    </a>
		{% endfor %}
	{% else %}
		<ul>Прайс обновляется.</ul>
	{% endif %}
</li>

Тут тоже особо ничего сложного нет и более подробно смотрите в видео. Если ничего не выведено, то сработает else "Прайс обновляется" smiley

Впринципе все, если будут какие либо вопросы Вы всегда можете написать мне.

Приношу извинения за плохое качество звука в видео.

Ваши комментарии

Комментарии могут оставлять только зарегистрированые пользователи!

Disqus - комментарии

blog comments powered by Disqus