Django实现展示CSV最新下载日期及新增用户数遇file_name未定义报错
错误原因
- 变量未持久化存储:
download_csv函数中生成的文件名是请求级临时变量,请求结束后就会销毁,download_page没有地方可以读取到这个变量,直接使用file_name就会报未定义错误。 - 拼写&语法错误:
account.views中文件名变量名拼写错误为file_naname,且赋值语句开头多了多余的+号download_page中new_profile行缩进错误,context字典的键值对之间缺少逗号,会触发语法报错
- 文件名拆分逻辑不可靠:原文件名直接拼接日期和数量,没有分隔符,按固定下标截取很容易出错。
修复方案
步骤1:新增下载记录模型(持久化存储下载信息)
在你的app的models.py中新增如下模型,执行python manage.py makemigrations和python manage.py migrate完成数据库迁移:
from django.db import models from datetime import datetime class CSVDownloadRecord(models.Model): download_date = models.DateField(default=datetime.today) profile_count_at_download = models.IntegerField() file_name = models.CharField(max_length=100) class Meta: # 默认按下载时间倒序排列,取第一条就是最新记录 ordering = ['-download_date']
步骤2:修改account.views的download_csv函数
修正拼写错误,新增下载记录存储逻辑:
@login_required def download_csv(request): import csv from datetime import datetime from .models import CSVDownloadRecord, Information response = HttpResponse(content_type='text/csv') profile_total = Information.objects.all().count() profile_csv_date_download = datetime.today().strftime("%d-%m-%Y") # 文件名用下划线分隔日期和数量,方便后续处理 file_name = f"{profile_csv_date_download}_{profile_total}.csv" response['Content-Disposition'] = f'attachment; filename={file_name}' writer = csv.writer(response, delimiter=';') info = Information.objects.all() writer.writerow(['first_name', 'last_name', 'gender', 'birthdate']) for i in info: writer.writerow([i.first_name, i.last_name, i.gender, i.birthdate]) # 保存本次下载记录 CSVDownloadRecord.objects.create( profile_count_at_download=profile_total, file_name=file_name ) return response
步骤3:修改download.views的download_page函数
从数据库读取最新下载记录,修正语法错误:
from .models import Information, CSVDownloadRecord def download_page(request): profile_total = Information.objects.all().count() # 取最新的下载记录 latest_record = CSVDownloadRecord.objects.first() if latest_record: latest_d_csv = latest_record.download_date.strftime("%d-%m-%Y") latest_n_csv = latest_record.profile_count_at_download new_profile = profile_total - latest_n_csv else: # 无下载记录时给默认值 latest_d_csv = "暂无下载记录" latest_n_csv = 0 new_profile = profile_total context = { 'profile_total': profile_total, 'latest_d_csv': latest_d_csv, 'latest_n_csv': latest_n_csv, 'new_profile': new_profile } return render(request, 'page/download.html', context)
步骤4:HTML模板无需修改
现有模板语法可以正常读取context中的变量展示数据。
轻量替代方案(无需建表)
如果不想新增数据库表,可以用Django缓存存储最新文件名,服务重启后缓存会清空,适合测试场景使用:
- 在
download_csv函数返回前添加代码:
from django.core.cache import cache # 永久缓存最新文件名 cache.set('latest_csv_name', file_name, timeout=None)
- 在
download_page函数开头添加代码:
from django.core.cache import cache file_name = cache.get('latest_csv_name', None) if file_name: date_str, count_str = file_name.rstrip('.csv').split('_') latest_d_csv = date_str latest_n_csv = int(count_str) new_profile = profile_total - latest_n_csv else: # 无下载记录默认值逻辑
内容的提问来源于stack exchange,提问作者Kome Gognome
相关产品推荐
相关产品推荐

