Django admin上传图片报TypeError: getattr属性名必须为字符串
问题现象
使用Django框架开发时,尝试通过admin站点上传图片,访问路径 /admin/imgUploader/images/add/ 时抛出TypeError异常,错误信息为 getattr(): attribute name must be string。
相关代码如下:
models.py代码
from distutils.command.upload import upload from email.mime import image from django.db import models from django.contrib.auth.models import User # def user_directory_path(instance, filename): # return 'user_{0}/{1}'.format(instance.user.id, filename) # Create your models here. class Images(models.Model): file = models.ImageField(#upload_to=user_directory_path, width_field=100, height_field=100, blank=True, null=True) name = models.CharField(max_length=30) description = models.TextField(help_text="Give a short description of the image", max_length=100) def __str__(self): return self.name
admin.py代码
from django.contrib import admin from .models import Images # Register your models here. admin.site.register(Images)
报错根因
- 核心问题是
ImageField的参数传值错误:width_field、height_field两个参数的作用是指定模型内用于存储图片实际宽度、高度的字段名,要求传入字符串类型的字段名,不能直接传入数值。 - 代码中直接给这两个参数传入整数
100,Django内部处理ImageField时会调用getattr()读取指定的模型字段属性,整数无法作为属性名传入getattr,直接触发该类型错误。 - 额外冗余:文件开头的
from distutils.command.upload import upload、from email.mime import image属于无用导入,不触发本次报错,但可以清理。 - 附带隐患:
ImageField的upload_to参数是必填项,修复参数错误后也需要正确配置该参数指定文件上传存储路径,否则会触发后续参数校验错误。 - 提供的
admin.py配置无问题,不需要修改。
修复方案
根据业务需求二选一即可:
方案1:不需要自动记录上传图片的宽高
直接移除width_field、height_field参数,正确配置upload_to参数即可,参考代码:
from django.db import models from django.contrib.auth.models import User def user_directory_path(instance, filename): return 'user_{0}/{1}'.format(instance.user.id, filename) class Images(models.Model): file = models.ImageField( upload_to=user_directory_path, blank=True, null=True ) name = models.CharField(max_length=30) description = models.TextField(help_text="Give a short description of the image", max_length=100) def __str__(self): return self.name
方案2:需要自动记录上传图片的宽高
先在模型中新增存储宽高的正整数字段,再将对应字段名以字符串形式传给width_field、height_field,参考代码:
from django.db import models from django.contrib.auth.models import User def user_directory_path(instance, filename): return 'user_{0}/{1}'.format(instance.user.id, filename) class Images(models.Model): # 新增存储宽高的字段,设置editable=False避免在admin表单中显示 width = models.PositiveIntegerField(editable=False, blank=True, null=True) height = models.PositiveIntegerField(editable=False, blank=True, null=True) file = models.ImageField( upload_to=user_directory_path, width_field="width", height_field="height", blank=True, null=True ) name = models.CharField(max_length=30) description = models.TextField(help_text="Give a short description of the image", max_length=100) def __str__(self): return self.name
修改完模型代码后,依次执行以下命令同步数据库变更:
python manage.py makemigrations python manage.py migrate
重启服务后再访问admin图片添加页即可正常使用上传功能。
内容的提问来源于stack exchange,提问作者Fife Oluwabunmi
相关产品推荐
相关产品推荐

