Files
diary-family/core/views.py
xiaji ab24c120e1 feat(报告系统): 添加汇总记录功能
新增汇总记录模型、表单、视图和模板,支持在报告中显示昨日汇总记录
2026-01-24 19:48:40 +08:00

807 lines
28 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse, JsonResponse
from django.utils import timezone
from django.db.models import Count
from django.core.mail import send_mail, EmailMessage
from django.conf import settings
from datetime import timedelta, datetime
import os
from loguru import logger
# WeasyPrint可用性标记初始为None
WEASYPRINT_AVAILABLE = None
# 获取WeasyPrint可用性
def is_weasyprint_available():
"""检查WeasyPrint是否可用"""
global WEASYPRINT_AVAILABLE
if WEASYPRINT_AVAILABLE is None:
try:
from weasyprint import HTML
# 测试WeasyPrint是否真正可用检查依赖库
test_html = HTML(string="<html><body>Test</body></html>")
# 尝试生成PDF以验证依赖库是否可用
import tempfile
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=True) as tmp:
test_html.write_pdf(tmp.name)
WEASYPRINT_AVAILABLE = True
logger.info("WeasyPrint库可用PDF功能正常")
except ImportError:
logger.warning("WeasyPrint库无法导入PDF功能将不可用")
WEASYPRINT_AVAILABLE = False
except Exception as e:
logger.warning(f"WeasyPrint依赖库不可用: {str(e)}PDF功能将不可用")
WEASYPRINT_AVAILABLE = False
return WEASYPRINT_AVAILABLE
from .models import (
ReadingRecord,
InsightRecord,
Summary,
FamilyTask,
TodayPlan,
SystemConfig,
FamilyMember,
SummaryCategory
)
from .forms import (
ReadingRecordForm,
InsightRecordForm,
SummaryForm,
FamilyTaskForm,
TodayPlanForm,
SystemConfigForm
)
# 首页视图
def index(request):
"""首页"""
logger.info("用户访问首页")
today = timezone.now().date()
yesterday = today - timedelta(days=1)
# 获取昨日记录
yesterday_reading = ReadingRecord.objects.filter(date=yesterday)
yesterday_insight = InsightRecord.objects.filter(date=yesterday)
# 获取今日计划
today_plan = TodayPlan.objects.filter(date=today)
# 获取待处理的家庭事项
pending_family_tasks = FamilyTask.objects.filter(status__name='pending')
context = {
'yesterday': yesterday,
'today': today,
'yesterday_reading': yesterday_reading,
'yesterday_insight': yesterday_insight,
'today_plan': today_plan,
'pending_family_tasks': pending_family_tasks,
}
return render(request, 'core/index.html', context)
# 昨日记录视图
def yesterday_records(request):
"""昨日记录"""
logger.info("用户访问昨日记录页面")
today = timezone.now().date()
yesterday = today - timedelta(days=1)
# 获取昨日阅读记录
reading_records = ReadingRecord.objects.filter(date=yesterday)
# 获取昨日感悟记录
insight_records = InsightRecord.objects.filter(date=yesterday)
context = {
'yesterday': yesterday,
'reading_records': reading_records,
'insight_records': insight_records,
}
return render(request, 'core/yesterday_records.html', context)
# 添加阅读记录
def add_reading(request):
"""添加阅读记录"""
if request.method == 'POST':
form = ReadingRecordForm(request.POST, request.FILES)
if form.is_valid():
reading = form.save(commit=False)
reading.date = timezone.now().date() - timedelta(days=1)
reading.save()
logger.info(f"添加阅读记录: {form.cleaned_data['title']}")
return redirect('yesterday_records')
else:
form = ReadingRecordForm()
context = {'form': form}
return render(request, 'core/add_reading.html', context)
# 编辑阅读记录
def edit_reading(request, pk):
"""编辑阅读记录"""
reading = get_object_or_404(ReadingRecord, pk=pk)
if request.method == 'POST':
form = ReadingRecordForm(request.POST, request.FILES, instance=reading)
if form.is_valid():
form.save()
logger.info(f"编辑阅读记录: {form.cleaned_data['title']}")
return redirect('yesterday_records')
else:
form = ReadingRecordForm(instance=reading)
context = {'form': form, 'reading': reading}
return render(request, 'core/edit_reading.html', context)
# 删除阅读记录
def delete_reading(request, pk):
"""删除阅读记录"""
reading = get_object_or_404(ReadingRecord, pk=pk)
if request.method == 'POST':
reading.delete()
logger.info(f"删除阅读记录: {reading.title}")
return redirect('yesterday_records')
context = {'reading': reading}
return render(request, 'core/delete_reading.html', context)
# 添加感悟记录
def add_insight(request):
"""添加感悟记录"""
family_members = FamilyMember.objects.all()
if request.method == 'POST':
form = InsightRecordForm(request.POST, request.FILES)
if form.is_valid():
insight = form.save(commit=False)
insight.date = timezone.now().date() - timedelta(days=1)
insight.save()
logger.info("添加感悟记录")
return redirect('yesterday_records')
else:
form = InsightRecordForm()
context = {'form': form, 'family_members': family_members}
return render(request, 'core/add_insight.html', context)
# 编辑感悟记录
def edit_insight(request, pk):
"""编辑感悟记录"""
insight = get_object_or_404(InsightRecord, pk=pk)
family_members = FamilyMember.objects.all()
if request.method == 'POST':
form = InsightRecordForm(request.POST, request.FILES, instance=insight)
if form.is_valid():
form.save()
logger.info("编辑感悟记录")
return redirect('yesterday_records')
else:
form = InsightRecordForm(instance=insight)
context = {'form': form, 'insight': insight, 'family_members': family_members}
return render(request, 'core/edit_insight.html', context)
# 删除感悟记录
def delete_insight(request, pk):
"""删除感悟记录"""
insight = get_object_or_404(InsightRecord, pk=pk)
if request.method == 'POST':
insight.delete()
logger.info("删除感悟记录")
return redirect('yesterday_records')
context = {'insight': insight}
return render(request, 'core/delete_insight.html', context)
# 今日记录视图
def today_records(request):
"""今日记录"""
logger.info("用户访问今日记录页面")
today = timezone.now().date()
# 获取今日阅读记录
reading_records = ReadingRecord.objects.filter(date=today)
# 获取今日感悟记录
insight_records = InsightRecord.objects.filter(date=today)
context = {
'today': today,
'reading_records': reading_records,
'insight_records': insight_records,
}
return render(request, 'core/today_records.html', context)
# 添加今日阅读记录
def add_today_reading(request):
"""添加今日阅读记录"""
if request.method == 'POST':
form = ReadingRecordForm(request.POST, request.FILES)
if form.is_valid():
reading = form.save(commit=False)
reading.date = timezone.now().date()
reading.save()
logger.info(f"添加今日阅读记录: {form.cleaned_data['title']}")
return redirect('today_records')
else:
form = ReadingRecordForm()
context = {'form': form}
return render(request, 'core/add_reading.html', context)
# 编辑今日阅读记录
def edit_today_reading(request, pk):
"""编辑今日阅读记录"""
reading = get_object_or_404(ReadingRecord, pk=pk)
if request.method == 'POST':
form = ReadingRecordForm(request.POST, request.FILES, instance=reading)
if form.is_valid():
form.save()
logger.info(f"编辑今日阅读记录: {form.cleaned_data['title']}")
return redirect('today_records')
else:
form = ReadingRecordForm(instance=reading)
context = {'form': form, 'reading': reading}
return render(request, 'core/edit_reading.html', context)
# 删除今日阅读记录
def delete_today_reading(request, pk):
"""删除今日阅读记录"""
reading = get_object_or_404(ReadingRecord, pk=pk)
if request.method == 'POST':
reading.delete()
logger.info(f"删除今日阅读记录: {reading.title}")
return redirect('today_records')
context = {'reading': reading}
return render(request, 'core/delete_reading.html', context)
# 添加今日感悟记录
def add_today_insight(request):
"""添加今日感悟记录"""
family_members = FamilyMember.objects.all()
if request.method == 'POST':
form = InsightRecordForm(request.POST, request.FILES)
if form.is_valid():
insight = form.save(commit=False)
insight.date = timezone.now().date()
insight.save()
logger.info("添加今日感悟记录")
return redirect('today_records')
else:
form = InsightRecordForm()
context = {'form': form, 'family_members': family_members}
return render(request, 'core/add_insight.html', context)
# 编辑今日感悟记录
def edit_today_insight(request, pk):
"""编辑今日感悟记录"""
insight = get_object_or_404(InsightRecord, pk=pk)
family_members = FamilyMember.objects.all()
if request.method == 'POST':
form = InsightRecordForm(request.POST, request.FILES, instance=insight)
if form.is_valid():
form.save()
logger.info("编辑今日感悟记录")
return redirect('today_records')
else:
form = InsightRecordForm(instance=insight)
context = {'form': form, 'insight': insight, 'family_members': family_members}
return render(request, 'core/edit_insight.html', context)
# 删除今日感悟记录
def delete_today_insight(request, pk):
"""删除今日感悟记录"""
insight = get_object_or_404(InsightRecord, pk=pk)
if request.method == 'POST':
insight.delete()
logger.info("删除今日感悟记录")
return redirect('today_records')
context = {'insight': insight}
return render(request, 'core/delete_insight.html', context)
# 汇总记录视图
def summaries(request):
"""汇总记录"""
logger.info("用户访问汇总记录页面")
today = timezone.now().date()
yesterday = today - timedelta(days=1)
summary_records = Summary.objects.filter(date=yesterday)
context = {
'yesterday': yesterday,
'summary_records': summary_records,
}
return render(request, 'core/summaries.html', context)
# 添加汇总记录
def add_summary(request):
"""添加汇总记录"""
family_members = FamilyMember.objects.all()
categories = SummaryCategory.objects.all()
if request.method == 'POST':
form = SummaryForm(request.POST, request.FILES)
if form.is_valid():
form.save()
logger.info(f"添加汇总记录: {form.cleaned_data['content'][:20]}...")
return redirect('summaries')
else:
form = SummaryForm()
context = {'form': form, 'family_members': family_members, 'categories': categories}
return render(request, 'core/add_summary.html', context)
# 编辑汇总记录
def edit_summary(request, pk):
"""编辑汇总记录"""
summary = get_object_or_404(Summary, pk=pk)
family_members = FamilyMember.objects.all()
categories = SummaryCategory.objects.all()
if request.method == 'POST':
form = SummaryForm(request.POST, request.FILES, instance=summary)
if form.is_valid():
form.save()
logger.info(f"编辑汇总记录: {form.cleaned_data['content'][:20]}...")
return redirect('summaries')
else:
form = SummaryForm(instance=summary)
context = {'form': form, 'summary': summary, 'family_members': family_members, 'categories': categories}
return render(request, 'core/edit_summary.html', context)
# 删除汇总记录
def delete_summary(request, pk):
"""删除汇总记录"""
summary = get_object_or_404(Summary, pk=pk)
if request.method == 'POST':
summary.delete()
logger.info(f"删除汇总记录: {summary.content[:20]}...")
return redirect('summaries')
context = {'summary': summary}
return render(request, 'core/delete_summary.html', context)
# 家庭事项视图
def family_tasks(request):
"""家庭事项"""
logger.info("用户访问家庭事项页面")
tasks = FamilyTask.objects.all()
context = {
'tasks': tasks,
}
return render(request, 'core/family_tasks.html', context)
# 添加家庭事项
def add_family_task(request):
"""添加家庭事项"""
if request.method == 'POST':
form = FamilyTaskForm(request.POST)
if form.is_valid():
form.save()
logger.info(f"添加家庭事项: {form.cleaned_data['content'][:20]}...")
return redirect('family_tasks')
else:
form = FamilyTaskForm()
context = {'form': form}
return render(request, 'core/add_family_task.html', context)
# 编辑家庭事项
def edit_family_task(request, pk):
"""编辑家庭事项"""
task = get_object_or_404(FamilyTask, pk=pk)
if request.method == 'POST':
form = FamilyTaskForm(request.POST, instance=task)
if form.is_valid():
form.save()
logger.info(f"编辑家庭事项: {form.cleaned_data['content'][:20]}...")
return redirect('family_tasks')
else:
form = FamilyTaskForm(instance=task)
context = {'form': form, 'task': task}
return render(request, 'core/edit_family_task.html', context)
# 删除家庭事项
def delete_family_task(request, pk):
"""删除家庭事项"""
task = get_object_or_404(FamilyTask, pk=pk)
if request.method == 'POST':
task.delete()
logger.info(f"删除家庭事项: {task.content[:20]}...")
return redirect('family_tasks')
context = {'task': task}
return render(request, 'core/delete_family_task.html', context)
# 今日计划视图
def today_plan(request):
"""今日计划"""
logger.info("用户访问今日计划页面")
today = timezone.now().date()
# 获取今日计划
plans = TodayPlan.objects.filter(date=today)
context = {
'today': today,
'plans': plans,
}
return render(request, 'core/today_plan.html', context)
# 添加今日计划
def add_today_plan(request):
"""添加今日计划"""
family_members = FamilyMember.objects.all()
if request.method == 'POST':
form = TodayPlanForm(request.POST)
if form.is_valid():
form.save()
logger.info(f"添加今日计划: {form.cleaned_data['content'][:20]}...")
return redirect('today_plan')
else:
form = TodayPlanForm()
context = {'form': form, 'family_members': family_members}
return render(request, 'core/add_today_plan.html', context)
# 编辑今日计划
def edit_today_plan(request, pk):
"""编辑今日计划"""
plan = get_object_or_404(TodayPlan, pk=pk)
family_members = FamilyMember.objects.all()
if request.method == 'POST':
form = TodayPlanForm(request.POST, instance=plan)
if form.is_valid():
form.save()
logger.info(f"编辑今日计划: {form.cleaned_data['content'][:20]}...")
return redirect('today_plan')
else:
form = TodayPlanForm(instance=plan)
context = {'form': form, 'plan': plan, 'family_members': family_members}
return render(request, 'core/edit_today_plan.html', context)
# 删除今日计划
def delete_today_plan(request, pk):
"""删除今日计划"""
plan = get_object_or_404(TodayPlan, pk=pk)
if request.method == 'POST':
plan.delete()
logger.info(f"删除今日计划: {plan.content[:20]}...")
return redirect('today_plan')
context = {'plan': plan}
return render(request, 'core/delete_today_plan.html', context)
# 切换今日计划状态
def toggle_today_plan(request, pk):
"""切换今日计划状态"""
plan = get_object_or_404(TodayPlan, pk=pk)
pending_status = Status.objects.get(name='pending')
completed_status = Status.objects.get(name='completed')
plan.status = completed_status if plan.status == pending_status else pending_status
plan.save()
logger.info(f"切换今日计划状态: {plan.content[:20]}... -> {plan.get_status_display()}")
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
return JsonResponse({'status': plan.status, 'status_text': plan.get_status_display()})
return redirect('today_plan')
# 生成报告
def generate_report(request):
"""生成报告"""
logger.info("用户访问报告生成页面")
today = timezone.now().date()
yesterday = today - timedelta(days=1)
# 获取昨日记录
yesterday_reading = ReadingRecord.objects.filter(date=yesterday)
yesterday_insight = InsightRecord.objects.filter(date=yesterday)
yesterday_summary = Summary.objects.filter(date=yesterday)
# 获取今日计划
today_plan = TodayPlan.objects.filter(date=today)
# 获取家庭事项统计
family_task_stats = FamilyTask.objects.values('type').annotate(count=Count('id'))
# 获取最近7天的日期列表用于生成历史PDF链接
historical_dates = []
for i in range(1, 8):
historical_date = today - timedelta(days=i)
historical_dates.append(historical_date)
# 检查是否有更早的PDF文件
has_earlier_pdfs = False
seven_days_ago = today - timedelta(days=7)
pdf_files = [f for f in os.listdir(settings.REPORTS_ROOT) if f.endswith('.pdf')]
for pdf_file in pdf_files:
try:
# 从文件名中提取日期
date_str = pdf_file.replace('report_', '').replace('.pdf', '')
file_date = datetime.strptime(date_str, '%Y-%m-%d').date()
if file_date < seven_days_ago:
has_earlier_pdfs = True
break
except Exception:
continue
context = {
'today': today,
'yesterday': yesterday,
'yesterday_reading': yesterday_reading,
'yesterday_insight': yesterday_insight,
'yesterday_summary': yesterday_summary,
'today_plan': today_plan,
'family_task_stats': family_task_stats,
'historical_dates': historical_dates,
'has_earlier_pdfs': has_earlier_pdfs,
}
return render(request, 'core/report.html', context)
# 查看报告
def view_report(request, date):
"""查看指定日期的报告"""
logger.info(f"用户查看报告: {date}")
report_date = datetime.strptime(date, '%Y-%m-%d').date()
yesterday = report_date - timedelta(days=1)
# 获取指定日期的记录
yesterday_reading = ReadingRecord.objects.filter(date=yesterday)
yesterday_insight = InsightRecord.objects.filter(date=yesterday)
yesterday_summary = Summary.objects.filter(date=yesterday)
today_plan = TodayPlan.objects.filter(date=report_date)
# 获取家庭事项统计
family_task_stats = FamilyTask.objects.values('type').annotate(count=Count('id'))
context = {
'today': report_date,
'yesterday': yesterday,
'yesterday_reading': yesterday_reading,
'yesterday_insight': yesterday_insight,
'yesterday_summary': yesterday_summary,
'today_plan': today_plan,
'family_task_stats': family_task_stats,
}
return render(request, 'core/report.html', context)
# 生成PDF报告
def generate_pdf_report(request, date):
"""生成PDF报告"""
if not is_weasyprint_available():
logger.error("WeasyPrint库不可用无法生成PDF报告")
return HttpResponse("PDF功能不可用请检查WeasyPrint库是否正确安装", status=500)
logger.info(f"用户生成PDF报告: {date}")
try:
report_date = datetime.strptime(date, '%Y-%m-%d').date()
yesterday = report_date - timedelta(days=1)
# 获取指定日期的记录
yesterday_reading = ReadingRecord.objects.filter(date=yesterday)
yesterday_insight = InsightRecord.objects.filter(date=yesterday)
yesterday_summary = Summary.objects.filter(date=yesterday)
today_plan = TodayPlan.objects.filter(date=report_date)
# 获取家庭事项统计
family_task_stats = FamilyTask.objects.values('type').annotate(count=Count('id'))
context = {
'today': report_date,
'yesterday': yesterday,
'yesterday_reading': yesterday_reading,
'yesterday_insight': yesterday_insight,
'yesterday_summary': yesterday_summary,
'today_plan': today_plan,
'family_task_stats': family_task_stats,
}
# 渲染HTML模板
html_string = render(request, 'core/report_pdf.html', context).content.decode('utf-8')
# 生成PDF
pdf_file = f"report_{date}.pdf"
pdf_path = os.path.join(settings.REPORTS_ROOT, pdf_file)
# 确保报告目录存在
os.makedirs(settings.REPORTS_ROOT, exist_ok=True)
# 动态导入WeasyPrint
from weasyprint import HTML
HTML(string=html_string).write_pdf(pdf_path)
logger.info(f"PDF报告生成成功: {pdf_path}")
# 返回PDF文件
with open(pdf_path, 'rb') as f:
response = HttpResponse(f.read(), content_type='application/pdf')
response['Content-Disposition'] = f'attachment; filename="{pdf_file}"'
return response
except Exception as e:
logger.error(f"生成PDF报告失败: {str(e)}")
return HttpResponse(f"生成PDF报告失败: {str(e)}", status=500)
# 预览PDF报告
def preview_pdf_report(request, date):
"""预览PDF报告HTML格式样式与PDF一致"""
logger.info(f"用户预览PDF报告: {date}")
try:
report_date = datetime.strptime(date, '%Y-%m-%d').date()
yesterday = report_date - timedelta(days=1)
# 获取指定日期的记录
yesterday_reading = ReadingRecord.objects.filter(date=yesterday)
yesterday_insight = InsightRecord.objects.filter(date=yesterday)
yesterday_summary = Summary.objects.filter(date=yesterday)
today_plan = TodayPlan.objects.filter(date=report_date)
# 获取家庭事项统计
family_task_stats = FamilyTask.objects.values('type').annotate(count=Count('id'))
context = {
'today': report_date,
'yesterday': yesterday,
'yesterday_reading': yesterday_reading,
'yesterday_insight': yesterday_insight,
'yesterday_summary': yesterday_summary,
'today_plan': today_plan,
'family_task_stats': family_task_stats,
}
# 渲染HTML模板与PDF使用相同的模板
return render(request, 'core/report_pdf.html', context)
except Exception as e:
logger.error(f"预览PDF报告失败: {str(e)}")
return HttpResponse(f"预览PDF报告失败: {str(e)}", status=500)
# 系统配置
def system_settings(request):
"""系统配置"""
logger.info("用户访问系统配置页面")
config = SystemConfig.get_config()
if request.method == 'POST':
form = SystemConfigForm(request.POST, instance=config)
if form.is_valid():
form.save()
logger.info("系统配置更新成功")
return redirect('system_settings')
else:
form = SystemConfigForm(instance=config)
context = {'form': form}
return render(request, 'core/system_settings.html', context)
# 发送邮件
def send_email_view(request):
"""手动发送邮件"""
if not is_weasyprint_available():
logger.error("WeasyPrint库不可用无法生成PDF报告")
return HttpResponse("PDF功能不可用无法发送邮件", status=500)
logger.info("用户手动发送邮件")
today = timezone.now().date()
today_str = today.strftime('%Y-%m-%d')
# 获取系统配置
config = SystemConfig.get_config()
if not all([config.smtp_server, config.smtp_username, config.smtp_password, config.recipient_email]):
logger.error("邮件配置不完整")
return redirect('system_settings')
# 生成PDF报告
report_date = today
yesterday = report_date - timedelta(days=1)
yesterday_reading = ReadingRecord.objects.filter(date=yesterday)
yesterday_insight = InsightRecord.objects.filter(date=yesterday)
yesterday_summary = Summary.objects.filter(date=yesterday)
today_plan = TodayPlan.objects.filter(date=report_date)
family_task_stats = FamilyTask.objects.values('type').annotate(count=Count('id'))
context = {
'today': report_date,
'yesterday': yesterday,
'yesterday_reading': yesterday_reading,
'yesterday_insight': yesterday_insight,
'yesterday_summary': yesterday_summary,
'today_plan': today_plan,
'family_task_stats': family_task_stats,
}
# 渲染HTML模板
html_string = render(request, 'core/report_pdf.html', context).content.decode('utf-8')
# 生成PDF
pdf_file = f"report_{today_str}.pdf"
pdf_path = os.path.join(settings.REPORTS_ROOT, pdf_file)
os.makedirs(settings.REPORTS_ROOT, exist_ok=True)
# 动态导入WeasyPrint
from weasyprint import HTML
HTML(string=html_string).write_pdf(pdf_path)
# 发送邮件
subject = f"家庭日报 - {today_str}"
message = f"这是您的家庭日报,日期:{today_str}"
from_email = config.smtp_username
recipient_list = [config.recipient_email]
email = EmailMessage(
subject=subject,
body=message,
from_email=from_email,
to=recipient_list,
)
# 添加附件
with open(pdf_path, 'rb') as f:
email.attach(pdf_file, f.read(), 'application/pdf')
# 发送邮件
try:
email.send()
logger.info(f"邮件发送成功,收件人:{config.recipient_email}")
return redirect('index')
except Exception as e:
logger.error(f"邮件发送失败:{str(e)}")
return redirect('system_settings')
# 别名保持URL配置一致
def send_email(request):
"""发送邮件别名"""
return send_email_view(request)
# PDF文件列表
def pdf_list(request):
"""显示服务器上已有的PDF文件列表"""
logger.info("用户访问PDF文件列表页面")
# 获取所有PDF文件
pdf_files = [f for f in os.listdir(settings.REPORTS_ROOT) if f.endswith('.pdf')]
# 解析文件名,提取日期,并按日期降序排序
pdf_info = []
for pdf_file in pdf_files:
try:
# 从文件名中提取日期
date_str = pdf_file.replace('report_', '').replace('.pdf', '')
file_date = datetime.strptime(date_str, '%Y-%m-%d').date()
pdf_info.append({
'filename': pdf_file,
'date': file_date,
'date_str': date_str
})
except Exception as e:
logger.error(f"解析PDF文件名失败: {pdf_file}, 错误: {str(e)}")
continue
# 按日期降序排序
pdf_info.sort(key=lambda x: x['date'], reverse=True)
context = {
'pdf_files': pdf_info
}
return render(request, 'core/pdf_list.html', context)