Django 的图片上传与显示 1: FileField 方法
Python 2.7.13
Django==1.19.5
后一篇:Django 的图片上传与显示 2: ImageFiled 方法
Django 处理图片的上传与显示,主要使用 models 的两种 Field 来处理图片:
- FieldField:优点是简单、不依赖第三方库;缺点是缺少对图片的复杂处理功能。
- ImageField:优点是可以对图片进行更多处理,比如可以获得图片的宽和高的像素大小、可以缩小图片等;缺点是需要依赖第三方库 pillow。
具体关于 FileField 和 ImageField 说明,也可以查看官方文档 FileField.
storage。
0 前置条件
需要设置好静态文件配置参数,参照
Django 开发时的静态文件配置参数以及 collectstatic
1 FileField 方法
1.1 设置 models 中的属性
在 posts/models.py 中设置 FileField,属性要运行为空和 null。因为可能不上传图片。
class Post(models.Model):
image = models.FileField(null=True, blank=True)
设置好之后需要数据迁移
$ python manage.py makemigrations
$ python manage.py migrate
在 posts/admin.py 中把 models 的 Post 这个类(数据表)注册进去。
from django.contrib import admin
from .models import Post
admin.site.register(Post)
开启服务器
$ python manage.py runserver 0.0.0.0:8080
进入后台 admin,在浏览器输入 127.0.0.1:8080/admin
,新建或者增加 post,可以看图片可以上传了。
图片上传以后,会直接保存在之前在参数设定中,用 MEDIA_ROOT 设置好的目录,名叫 media_cdn
。
1.2 forms 和 views
如果使用 form 表单验证,forms.py 的设置如下
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = [
"image",
]
而对于 views 函数,如果是创建一个空的 form 用于提交。这里使用了 forms 表单验证,参数需要加入 request.FILES or None
,否则会报错。
from django.shortcuts import redirect
from .models import Post
def post_create(request):
form = PostForm(request.POST or None, request.FILES or None)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
return redirect(reverse("detail", kwargs={"id": instance.id}))
context = {
"form": form,
}
return render(request, "post_form.html", context)
def post_detail(request, id=None):
instance = get_object_or_404(Post, id=id)
context = {
"instance": instance,
}
return render(request, "post_detail.html", context)
对于路由而言,create 是创建表单,带变量 id 则是获得该 id 的详情。
from django.conf.urls import url
urlpatterns = [
url(r'^create/$', "posts.views.post_create"),
url(r'^(?P<id>\d+)/$',"posts.views.post_detail", name='detail'),
# ...
]
1.3 Django 模板中的使用
form 提交
对于 form 的文件上传,一定要在 form 标签中使用 enctype='multipart/form-data'
属性,完整的属性设置如下:
templates/post_form.html
<form methdo='POST' action='' enctype='multipart/form-data'>
{{ form.as_p }}
<input type="submit" value="create post" name="">
{% csrf_token %}
</form>
其中 action=''
表示提交到当前页面。
图片显示
templates/post_detail.html
{% if instance.image %}
![]({{ instance.image.url }})
{% endif %}
代码用图片显示为:
image_src_url.png需要对传过来的表单数据 instance进行判断,存在图片再显示。