Django博客搭建_其他模块-文档下载

Blog项目——其他模块

一、分析

业务处理流程:

  • 判断前端传的文件id是否为空,对应的文件是否存在

请求方法GET

url定义/docs/<int:doc_id>/

请求参数:url路径参数

参数类型前端是否必须传描述
doc_id整数文件id

此功能是通过向前端返回FileResponse来实现的。

二、模型实现

应为文档的模型并没有创建,因此我们需要先创建app,并且进行注册。代码就不演示了,下面直接说模型部分。

模型所需的字段:

  • 文件地址
  • 书籍的标题
  • 数据的描述
  • 书籍封面图
  • 作者
# doc/models.py
from django.db import models
from utils.BaseModel import ModelBase


class Docs(ModelBase):
	"""
	文件地址
	书籍的标题
	书籍的描述信息
	书籍的封面图
	作者
	"""
	file_url = models.URLField("文件地址", help_text="书籍地址")
	title = models.CharField("书籍标题", max_length=150)
	desc = models.TextField("书籍描述")
	image_url = models.URLField("书籍封面", default="")
	auther = models.ForeignKey("user.Users", on_delete=models.SET_NULL, null=True)

	class Meta:
		db_table = "tb_docs"
		verbose_name = "书籍"

	def __str__(self):
		return self.title

接下来就是执行迁移即可

剩下的就是将sql文件导入。

mysql -uuser -ppsw -D database < tb_docs.sql 

三、路由注册

首先先进入主路由,将doc的路由放入

# blog_django/urls
path('docs/',include('docs.urls')),

接下来就是进入doc路由,创建urls文件,

# -*- coding: utf-8 -*-
# @Auther:Summer
from django.urls import path

app_name = "news"

urlpatterns = [
	
]

四、后端代码实现

在请求资源的时候,我们要使用request库,我们这个地方也需要使用,因此需要提前安装

pip install requests
# 在Blog_Djnago/settings.py中加入如下配置 

# 站点域名和端口配置
DOC_FILE_URL = "http://127.0.0.1:8000"

视图部分

# doc/views.py
from django.shortcuts import render
from django.views import View
from django.http import HttpResponse, FileResponse, Http404
from django.utils.encoding import escape_uri_path

from .models import Docs
from Blog_Django.settings import DOC_FILE_URL
import requests


def doc(request):
	docs = Docs.objects.only("image_url", "title", "desc").filter(is_delete=False)
	return render(request, "doc/docDownload.html", context={"docs":docs})


class DocDownload(View):
	def get(self, request, doc_id):
		doc_file = Docs.objects.only("file_url").filter(is_delete=False,id=doc_id).first()
		if doc_file:
			doc_url = doc_file.file_url
			doc_url = DOC_FILE_URL + doc_url

			# res = HttpResponse(requests.get(doc_url))  # 如果使用这个,可能会产生文件过大而导致系统堵塞
			res = FileResponse(requests.get(doc_url))  # 分批写入用户的内存,一个批次4096

			# 获取尾坠,查看格式
			ex_name = doc_url.split(".")[-1]

			if not ex_name:
				raise Http404("文件名异常")
			else:
				ex_name = ex_name.lower()

			if ex_name == 'pdf':
				res['Content-type'] = 'application/pdf'

			elif ex_name == 'doc':
				res['Content-type'] = 'application/msowrd'

			elif ex_name == 'ppt':
				res['Content-type'] = 'application/powerpoint'

			else:
				raise Http404('文件格式不正确')

			doc_filename = escape_uri_path(doc_url.split("/")[-1])

			# attachment  保存  inline 显示
			res["Content-Disposition"] = "attachment; filename*=UTF-8''{}".format(doc_filename)
			return res

		else:
			raise Http404('文档不存在')

路由部分

# -*- coding: utf-8 -*-
# @Auther:Summer
from django.urls import path
from . import views

app_name = "doc"

urlpatterns = [
	path("", views.doc),
	path("download/<int:doc_id>", views.DocDownload.as_view(), name="download"),
]

五、前端代码实现

html部分

{% extends "base/base.html" %}

{% block title %}
    payInfo
{% endblock %}

{% block link %}
    <link rel="stylesheet" href="../../static/css/doc/docDownload.css">
{% endblock %}

{% block main_contain %}
    <div class="main-contain ">
            <div class="banner">
                <img src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1802845035,3786939119&fm=26&gp=0.jpg"
                     alt="">
            </div>
            <div class="pay-doc-contain">
                <ul class="pay-list">
                    {% for doc in docs %}
                        <li class="pay-item">
                            <img src="{{ doc.image_url }}" alt="{{ doc.title }}" class="pay-img doc">
                            <div class="d-contain">
                                <p class="doc-title">{{ doc.title }}</p>
                                <p class="doc-desc">{{ doc.desc }}</p>

                                <!-- /www/?xxx -->
                                <a href="{% url 'doc:download' doc.id %}" class="pay-price">下载</a>
                            </div>
                        </li>
                    {% endfor %}
                </ul>
            </div>
        </div>
{% endblock %}

css部分

/* ================= main start ================= */
#main {
    margin-top: 25px;
    min-height: 700px;
    flex: 1;
}

/* ========= main-contain start ============ */
#main .main-contain {
    width: 800px;
    float: left;
    margin-bottom: 30px;
}

/* ========= banner start =========== */
.main-contain .banner {
    width: 100%;
}

.main-contain .banner img {
    max-width: 100%;
}

.main-contain .pay-doc-contain {
    background: #fff;
}

.main-contain .pay-doc-contain .pay-list {
    display: flex;
    justify-content: space-between;
    flex-flow: wrap;
    padding: 0 20px 20px;
}

.main-contain .pay-doc-contain .pay-item {
    width: 800px;
    height: 200px;
    border-top: 1px solid #ddd;
    margin-top: 20px;
    display: flex;
}

.main-contain .pay-doc-contain .pay-item:hover {
    box-shadow: 2px 2px 2px #ccc;
}

.pay-doc-contain .pay-item .pay-img {
    width: 120px;
    margin-right: 30px;
}

.pay-doc-contain .pay-item .pay-contain {
    width: 250px;
    position: relative
}

.pay-item .pay-contain .pay-title {
    font-size: 20px;
    line-height: 40px;
    white-space: nowrap;
    overflow: hidden;
}

.pay-item .pay-contain .pay-desc {
    line-height: 20px;
    color: #878787;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    font-size: 14px;
    overflow: hidden;
}

.pay-item .pay-price {
    display: block;
    font-size: 20px;
    text-align: right;
    padding-right: 20px;
    color: coral;
}

.d-contain {
    width: 100%;
    margin: 20px 0 20px ;
    font-size: 18px;
    line-height: normal;
}

.d-contain .doc-desc {
    text-indent: 2em;
    margin: 15px;
    /*padding: 10px;*/
}

.d-contain .doc-title {
    font-size: 20px;
    font-weight: bold;
    color: chocolate;
}
/* ========= banner end =========== */
/* ========= main-contain end ============ */
/* ================= main end ================= */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值