25人参与 • 2025-08-23 • Python
文件上传 → 保存到 media_root/upload_to/ → 数据库记录路径
""" django 脚本上传文件到 imagefield 完整示例 """ import os import sys import django from pathlib import path from django.core.files import file import logging # 配置日志 logger = logging.getlogger(__name__) logging.basicconfig( level=logging.info, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.filehandler('upload_script.log'), logging.streamhandler() ] ) def setup_django(): """配置 django 环境""" # 获取项目根目录 base_dir = path(__file__).resolve().parent.parent.parent # 添加到系统路径 sys.path.append(str(base_dir)) # 设置 django 环境变量 os.environ.setdefault('django_settings_module', 'yuncoolcinema.settings') # 初始化 django django.setup() # 导入 django 设置 from django.conf import settings return settings def upload_file_to_model(model, file_path, field_name='avatar', **kwargs): """ 上传文件到模型字段 :param model: 模型实例 :param file_path: 文件路径 :param field_name: 字段名称 :param kwargs: 模型过滤条件 :return: 更新后的模型实例 """ # 获取文件字段 file_field = getattr(model, field_name) # 打开文件 with open(file_path, 'rb') as f: # 保存文件到字段 file_field.save( path(file_path).name, # 文件名 file(f), # 文件内容,转换成django内部的文件对象 save=true # 保存模型 ) logger.info('文件已上传: %s -> %s', file_path, file_field.path) return model def main(): """主函数""" # 1. 设置 django 环境 settings = setup_django() logger.info('django 环境设置完成') # 2. 导入模型 from actors.models import actor # 3. 设置文件目录 file_dir = path('data/portrait') # 文件源目录 if not file_dir.exists(): logger.error('文件目录不存在: %s', file_dir) return # 4. 获取演员和文件映射 # 假设文件名格式: {演员姓名}.jpg file_map = {} for file_path in file_dir.glob('*.*'): if file_path.suffix.lower() in ['.jpg', '.jpeg', '.png']: actor_name = file_path.stem # 文件名(不带扩展名) file_map[actor_name] = file_path # 5. 批量上传文件 success_count = 0 for actor_name, file_path in file_map.items(): try: # 获取演员对象 actor = actor.objects.get(name=actor_name) # 上传文件 upload_file_to_model(actor, file_path) success_count += 1 except actor.doesnotexist: logger.warning('演员不存在: %s', actor_name) except exception as e: logger.error('上传失败: %s - %s', actor_name, str(e)) logger.info('文件上传完成: 成功 %d 个', success_count) if __name__ == "__main__": main()
def setup_django(): base_dir = path(__file__).resolve().parent.parent.parent sys.path.append(str(base_dir)) os.environ.setdefault('django_settings_module', 'yuncoolcinema.settings') django.setup() from django.conf import settings return settings
def upload_file_to_model(model, file_path, field_name='avatar', **kwargs): file_field = getattr(model, field_name) with open(file_path, 'rb') as f: file_field.save( path(file_path).name, # 文件名 file(f), # 文件内容 save=true # 保存模型 )
file_field.save()
file
对象save=true
:自动保存模型到数据库# 上传后文件保存位置 file_path = model.avatar.path # 物理路径: media_root/portrait/filename.jpg file_url = model.avatar.url # 访问url: media_url/portrait/filename.jpg
media_root/upload_to/filename
# settings.py # 媒体文件配置 media_url = '/media/' # 访问url media_root = os.path.join(base_dir, 'media') # 文件存储路径
# urls.py from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # ...其他url... ] if settings.debug: urlpatterns += static(settings.media_url, document_root=settings.media_root)
# 自定义文件名 def custom_filename(instance, filename): """生成自定义文件名""" return f"portrait/{instance.id}_{filename}" # 在模型中 avatar = models.imagefield(upload_to=custom_filename)
import uuid def unique_filename(instance, filename): """生成唯一文件名""" ext = filename.split('.')[-1] return f"portrait/{uuid.uuid4().hex}.{ext}"
def bulk_upload(models, file_map, field_name): """批量上传文件""" for model in models: if model.name in file_map: upload_file_to_model(model, file_map[model.name], field_name)
from tqdm import tqdm # 在循环中使用 for actor_name, file_path in tqdm(file_map.items(), desc="上传文件"): # 上传逻辑
from django.core.exceptions import validationerror def validate_image(file_path): """验证图片文件""" # 检查文件大小 if file_path.stat().st_size > 5 * 1024 * 1024: # 5mb raise validationerror("文件大小超过限制") # 检查文件类型 if file_path.suffix.lower() not in ['.jpg', '.jpeg', '.png']: raise validationerror("不支持的文件类型")
try: upload_file_to_model(actor, file_path) except oserror as e: logger.error('文件操作错误: %s', str(e)) except django.db.utils.integrityerror as e: logger.error('数据库错误: %s', str(e)) except exception as e: logger.exception('未知错误')
# settings.py default_file_storage = 'storages.backends.s3boto3.s3boto3storage' aws_access_key_id = 'your-access-key' aws_secret_access_key = 'your-secret-key' aws_storage_bucket_name = 'your-bucket-name' aws_s3_region_name = 'your-region'
def cleanup_old_file(model, field_name): """清理旧文件""" old_file = getattr(model, field_name) if old_file and old_file.name: old_file.delete(save=false) # 删除文件但不保存模型
from django.core.cache import cache def get_cached_model(model_class, pk): """获取缓存模型""" cache_key = f"{model_class.__name__}_{pk}" model = cache.get(cache_key) if not model: model = model_class.objects.get(pk=pk) cache.set(cache_key, model, timeout=60 * 60) # 缓存1小时 return model
# 创建虚拟环境 python -m venv .venv source .venv/bin/activate # linux/macos .\.venv\scripts\activate # windows # 安装依赖 pip install django tqdm
project/ ├── manage.py ├── media/ # 上传的文件存储位置 (自动创建) ├── data/ # 原始文件目录 │ └── portrait/ │ ├── 张艺谋.jpg │ └── 巩俐.png ├── scripts/ │ └── upload_files.py # 上传脚本 └── yuncoolcinema/ ├── settings.py ├── urls.py └── actors/ ├── models.py └── ...
python scripts/upload_files.py
# 在django shell中验证 from actors.models import actor actor = actor.objects.get(name="张艺谋") print(actor.avatar.url) # 输出: /media/portrait/张艺谋.jpg
文件保存在 media_root/upload_to/
目录下,其中:
media_root
在 settings.py 中定义upload_to
在模型字段中定义在模板中使用:
<img src="{{ actor.avatar.url }}" alt="{{ actor.name }}">
确保在开发环境中配置了媒体文件服务。
uuid
生成唯一文件名# 更新文件时自动删除旧文件 def save(self, *args, **kwargs): if self.pk: # 检查是否是更新操作 old = actor.objects.get(pk=self.pk) if old.avatar != self.avatar: # 检查头像是否更改 old.avatar.delete(save=false) # 删除旧文件 super().save(*args, **kwargs)
通过本教程,您学会了:
关键点:
file_field.save()
方法上传文件media_root
正确配置media_root/upload_to/
目录media_root
)通过实现这些技术,您可以轻松地通过脚本将文件上传到 django 的 imagefield 字段,并确保文件保存在正确的位置。
以上就是django通过脚本上传文件的详细操作指南的详细内容,更多关于django脚本上传文件的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论