Django中如何将DetailView视图内运算得到的数据传递到模板
解决方案
你需要重写DetailView的get_context_data方法,这是Django类视图专门用于往模板传递额外上下文数据的入口,你运算得到的PDF页数、提取文本、搜索结果都可以放到该方法返回的上下文字典中,模板即可直接调用。
调整后的views.py代码
# 原有导入保留,比如PyPDF2、search方法对应的导入等 class PostDetailView(DetailView): context_object_name = "object_list" template_name = "post_detail.html" # 直接指定model,无需手动写get_object查实例,Django会自动处理 model = FileUpload def get_context_data(self, **kwargs): # 先获取默认上下文(已包含查询到的FileUpload实例) context = super().get_context_data(**kwargs) # 取出当前查询到的文件实例 file_instance = self.object # 原有PDF处理逻辑迁移到此处 try: pdfFileObj = open(file_instance.file.path, 'rb') pdfReader = PyPDF2.PdfFileReader(pdfFileObj) # 将运算结果逐一存入上下文 context['pdf_page_num'] = pdfReader.numPages pageObj = pdfReader.getPage(0) context['pdf_extract_text'] = pageObj.extractText() search_list = [] for j in search(context['pdf_extract_text'], tld="co.in", num=10, stop=10, pause=2): search_list.append(j) context['search_result'] = search_list pdfFileObj.close() except: context['process_err'] = "文件处理失败,请确认上传的是有效PDF文件" return context
模板调用示例(post_detail.html)
你在上下文里存入的变量可以直接在模板中调用:
<!-- 模型原有属性调用方式不变 --> <p>上传用户:{{ object_list.author }}</p> <a href="{{ object_list.file.url }}">下载原文件</a> <!-- 运算得到的非模型属性直接调用对应key即可 --> <p>PDF总页数:{{ pdf_page_num }}</p> <div>提取的第一页内容:{{ pdf_extract_text }}</div> <h3>搜索结果:</h3> <ul> {% for item in search_result %} <li>{{ item }}</li> {% empty %} <li>未找到匹配结果</li> {% endfor %} </ul> {% if process_err %} <p style="color: #f00;">{{ process_err }}</p> {% endif %}
替代方案(无需迁移原有逻辑)
如果你不想改动现有get_object里的逻辑,也可以直接在get_object中给实例临时绑定属性,模板同样可以调用:
def get_object(self, *args,**kwargs): request = self.request pk = self.kwargs.get('pk') instance = FileUpload.objects.get(id = pk) if instance is None: raise Http404("File Does not EXIST") else: pdfFileObj = open(instance.file.path, 'rb') pdfReader = PyPDF2.PdfFileReader(pdfFileObj) # 给实例绑定临时属性,不会写入数据库 instance.pdf_page_num = pdfReader.numPages pageObj = pdfReader.getPage(0) instance.pdf_text = pageObj.extractText() search_list = [] for j in search(instance.pdf_text, tld="co.in", num=10, stop=10, pause=2): search_list.append(j) instance.search_result = search_list pdfFileObj.close() return instance
模板中直接通过模型实例调用即可:
<p>总页数:{{ object_list.pdf_page_num }}</p> <p>提取文本:{{ object_list.pdf_text }}</p>
内容的提问来源于stack exchange,提问作者Huma Qureshi
相关产品推荐
相关产品推荐

