一, 关于 media 的设置
django 的 media 文件地址的设置其实是类似于 static 文件地址的设置.
media 主要是用来存放一些用户上传的文件(头像, 图片等)
分为三个部分:
一是在 proj 中建立一个 media 文件夹, 文件夹名字可任意取, 为方便起见, 此处就取名为 media.
二是在 setting 中设置 MEDIA_ROOT 和 MEDIA_URL
- # 用户文件存放位置
- MEDIA_ROOT= os.path.join(BASE_DIR,'media')
- MEDIA_URL = '/media/'
MEDIA_URL 是 media 文件夹的 url 地址, 也就是在前端访问时, 使用 /media/ 这个 url, 到后端 django 会自动将该 URL 转换为 MEDIA_ROOT 这个实际地址, 但是需要进行第三步设置之后才能够进行自动转换.
三是在 proj 的 url 中进行设置:
- from django.contrib import admin
- from django.urls import path, include
- from django.conf.urls.static import static
- from zl_prac import settings
- urlpatterns = [
- path('admin/', admin.site.urls),
- ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
也就是在 urlpatterns 后进行转换.
二, 关于文件上传地址 upto 的设置
用 django 开发, 经常要处理用户上传的文件, 比如 user 模型里面如果又个人头像的字段 ImageField 等等, 而 django 在 FielField 字段 (包括 ImageField) 的支持和扩展是做的很好的, 首先一个问题, 是上传的文件怎样才能放到我们想要放大的位置( 文件流是不会放到数据库里面的, 该字段在数据库中只存储路径).
一般情况下, 用户上传的文件可以放在 media/username 下的细分文件夹, 但是如何为不同的用户指定不同的路径呢?
django 提供了 upload_to 属性
以下介绍 upload_to 的具体使用方法.
注意:
如果 setting 中已经指定了 media 设置, 那么, upload_to 中的文件地址只要是相对地址, 则都是存放在 media 文件夹下的. 如果没有设置, 则存放在根目录下.
下面的方法都是默认设置了 media 文件夹.
如果 upload_to 中的指定的文件夹不存在, 则会自动创建.
1. 直接指定固定地址:
在 model 中直接指定一个固定的地址
- class User(models.Model):
- avatar = ImageField(upload_to = 'avatar/')
实际存放地址为 media/avatar/filename
2. 使用 strftime 函数
如果指定固定文件夹, 则可能会存在多人上传的不同文件重名情况, 这时候需要解决文件名冲突. 方法就是按照上传的时间不同来存放.
为了避免重名, django 在 upload_to 上内置了 strftime()函数. 将时间插入
- # models.py
- class User(models.Model):
- avatar = ImageField(upload_to = 'avatar/%Y/%m/%d/')
%Y,%m,%d 分别表示年, 月, 日
存储路径为 media/avatar / 年 / 月 / 日
3. 利用函数生成地址
以上两种方式都不能解决不同的用户使用不同的文件夹的情况. 可以使用自定义函数来解决这个问题:
- # 让上传的文件路径动态地与 user 的名字有关
- def upload_to(instance, fielname): #返回一个路径名即可. 调用时会自动传入 user 实例和 filename 两个参数. 函数名也不一定需要叫 upload_to, 只要传入此函数即可.
- return '/'.join([MEDIA_ROOT, instance.user_name, filename])
- class User(models.Model):
- avatar = ImageField(upload_to = upload_to)
- user_name = CharField(max_length = 250)
这里定义的 upload_to 返回的是一个绝对地址, 改地址保存在数据库中, 但是不利于网络的访问, 需要就行如下修改:
- def up_to(instance, filename):
- return '/'.join([instance.uid, str(int(time.time())) + '_' + filename])
此函数返回的是一个相对地址, django 会自动将该相对地址放在 media 之下.
其真实存储地址为 /media / 返回地址
数据库中则直接存放的是返回的地址.
这样前端想访问时, 直接使用:
<img id="img_thumbnail" src="/media/{{ user.avatar}}" alt="头像">
注意, 在前端使用的这个 /media/ , 并不是真正的 meida 文件夹, 而是在 setting 中设置的 MEDIA_URL.
来源: http://www.bubuko.com/infodetail-3122233.html