对于这个错误,也在于自己对django基础的掌握不是很牢固,忽略了MEDIA_ROOT的类型是string,而不是list。
错误的写法:
1 MEDIA_ROOT = [ 2 os.path.join(BASE_DIR, 'media'), 3 ]
正确的写法:
1 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
正是因为上面错误的将media_root的数据类型写错,才会导致了这么一个错误。
附上官方文档:
1 MEDIA_ROOT¶ 2 Default: '' (Empty string) 3 4 Absolute filesystem path to the directory that will hold user-uploaded files. 5 6 Example: "/var/www/example.com/media/"
说了这么多,MEDIA_ROOT的功能到底是干嘛用的呢,主要就是为我们上传一些图片、文件之类的资源提供了文件路径的功能。具体的使用如下:
settings.py
1 # MEDIA配置 2 MEDIA_URL = '/media/' 3 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
models.py
1 class Banner(models.Model): 2 """"轮播图""" 3 title = models.CharField('标题', max_length=100) 4 image = models.ImageField('轮播图', max_length=100, upload_to="banner/%Y/%m") # here, upload img 5 url = models.URLField('访问地址', max_length=200) 6 index = models.IntegerField('顺序', default=100) 7 add_time = models.DateTimeField('添加时间', default=datetime.datetime.now) 8 9 class Meta: 10 verbose_name = "轮播图" 11 verbose_name_plural = verbose_name 12 13 def __str__(self): 14 return self.title
urls.py
1 from django.urls import re_path 2 from django.views.static import serve 3 from django.conf import settings 4 5 6 urlpatterns = [ 7 ... ... 8 re_path('^media/(?P<path>.*)/$', serve, {"document_root": settings.MEDIA_ROOT}), 9 ] 10 11 12 # 或者另外一种方法 13 from django.conf.urls.static import static 14 from django.views.static import serve 15 from django.conf import settings 16 17 ... 18 19 urlpatterns += static(settings.MEDIA_URL, document_root=MEDIA_ROOT)
图片的上传,我们需要用到ImageField字段,并对其upload_to参数传入一个路径"banner/%Y/%m",这个路径会自动拼接到MEDIA_ROOT后面,例如这样:“/media/banner/12/04/xxx.jpg”。
【注】:ImageField的使用需要Pillow的支持,所以需要:pip install Pillow
为什么
为什么upload_to能够将后面的相对路径接到MEDIA_ROOT后面呢?这里面设计django框架的一个设计---文件系统(FileSystemStorage),django默认在orm中使用ImageField或者FileField时中upload_to所指向的路径将会被添加到MEDIA_ROOT后面,以在本地文件系统上形成将存储上传文件的位置。
这个upload_to有这么一个作用:
This attribute provides a way of setting the upload directory and file name, and can be set in two ways. In both cases, the value is passed to the Storage.save() method. 中文:此属性提供了设置上载目录和文件名的方法,可以通过两种方式进行设置。 在这两种情况下,该值都将传递给Storage.save()方法。
具体我们可参考如下:FileField字段
那么它是怎么生效的呢?在django中有一个global_settings.py文件,里面有file文件系统存储的默认设置,如下:
1 # Default file storage mechanism that holds media. 2 DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
从这里我们能看到django已经默认了一个文件存储器来工作了,它会全局控制django项目中的文件存储系统。
当然,我们也可以不使用这个默认的存储系统,自己写一个,或者使用别人的,参考官网链接:自定义存储系统