保存包含ImageField的Django模型时的TypeError

时间:2017-08-12 22:02:26

标签: python django django-models

我有一个基本模型,我添加了ImageField

class Category(models.Model):
    name = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(blank=True, editable=False)
    image = models.ImageField(upload_to='images', blank=True)

    def __str__(self):
        """
            Field to show in the related models admin site.
        """
        return self.name

    class Meta:
        # order of drop-down list items
        ordering = ('name',)

        # plural form in admin view
        verbose_name_plural = 'categories'

    def save(self, *args, **kwargs):
        """
            Save slug when saving model.
            Slug saved only if not existant, to avoid duplicity of urls.
        """
        if not self.id:
            # new object to create
            self.slug = slugify(self.name)[:50]

        super().save(*args, **kwargs)

当我尝试通过在admin中设置图片来创建/更新ImageField部分中的项目时,我收到以下错误({{{}时出现此错误1}}没有设置):

ImageField

Internal Server Error: /admin/app/category/8/change/ Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/django/core/handlers/exception.py", line 39, in inner response = get_response(request) File "/usr/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response response = self.process_exception_by_middleware(e, request) File "/usr/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/usr/lib/python3.6/site-packages/django/contrib/admin/options.py", line 544, in wrapper return self.admin_site.admin_view(view)(*args, **kwargs) File "/usr/lib/python3.6/site-packages/django/utils/decorators.py", line 149, in _wrapped_view response = view_func(request, *args, **kwargs) File "/usr/lib/python3.6/site-packages/django/views/decorators/cache.py", line 57, in _wrapped_view_func response = view_func(request, *args, **kwargs) File "/usr/lib/python3.6/site-packages/django/contrib/admin/sites.py", line 211, in inner return view(request, *args, **kwargs) File "/usr/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1512, in change_view return self.changeform_view(request, object_id, form_url, extra_context) File "/usr/lib/python3.6/site-packages/django/utils/decorators.py", line 67, in _wrapper return bound_func(*args, **kwargs) File "/usr/lib/python3.6/site-packages/django/utils/decorators.py", line 149, in _wrapped_view response = view_func(request, *args, **kwargs) File "/usr/lib/python3.6/site-packages/django/utils/decorators.py", line 63, in bound_func return func.__get__(self, type(self))(*args2, **kwargs2) File "/usr/lib/python3.6/contextlib.py", line 53, in inner return func(*args, **kwds) File "/usr/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1449, in changeform_view self.save_model(request, new_object, form, not add) File "/usr/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1007, in save_model obj.save() File "/home/hakim/project/app/models.py", line 103, in save super().save(*args, **kwargs) File "/usr/lib/python3.6/site-packages/django/db/models/base.py", line 796, in save force_update=force_update, update_fields=update_fields) File "/usr/lib/python3.6/site-packages/django/db/models/base.py", line 824, in save_base updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields) File "/usr/lib/python3.6/site-packages/django/db/models/base.py", line 886, in _save_table for f in non_pks] File "/usr/lib/python3.6/site-packages/django/db/models/base.py", line 886, in <listcomp> for f in non_pks] File "/usr/lib/python3.6/site-packages/django/db/models/fields/files.py", line 292, in pre_save file.save(file.name, file, save=False) File "/usr/lib/python3.6/site-packages/django/db/models/fields/files.py", line 91, in save self.name = self.storage.save(name, content, max_length=self.field.max_length) File "/usr/lib/python3.6/site-packages/django/core/files/storage.py", line 53, in save name = self.get_available_name(name, max_length=max_length) File "/usr/lib/python3.6/site-packages/django/core/files/storage.py", line 77, in get_available_name while self.exists(name) or (max_length and len(name) > max_length): File "/usr/lib/python3.6/site-packages/django/core/files/storage.py", line 394, in exists return os.path.exists(self.path(name)) File "/usr/lib/python3.6/site-packages/django/core/files/storage.py", line 407, in path return safe_join(self.location, name) File "/usr/lib/python3.6/site-packages/django/utils/functional.py", line 35, in __get__ res = instance.__dict__[self.name] = self.func(instance) File "/usr/lib/python3.6/site-packages/django/core/files/storage.py", line 283, in location return abspathu(self.base_location) File "/usr/lib/python3.6/posixpath.py", line 369, in abspath path = os.fspath(path) TypeError: expected str, bytes or os.PathLike object, not tuple 的相关部分:

settings.py

3 个答案:

答案 0 :(得分:1)

错误表明问题是存在元组而不是以下行中的字符串,其中path是上传文件的位置:

path = os.fspath(path)

由于upload_to被正确设置为模型中的字符串,我认为问题可能与MEDIA_ROOT有关,后者原来是一个元组(在评论中已澄清)。使它成为一个字符串解决了这个问题。

答案 1 :(得分:0)

出现这个错误:

TypeError: expected str, bytes or os.PathLike object, not tuple

我认为错误发生在表单的图像字段中。在save()中执行第一个:

print(self.image)

要查看您要保存的内容,它将是一个元组而不是字符串。

答案 2 :(得分:0)

就我而言,我有这样的想法:

MEDIA_ROOT=[os.path.join(BASE_DIR,'media')]

以这种方式编写解决了错误:

MEDIA_ROOT=os.path.join(BASE_DIR,'media')