做项目中的一个坑。。
本来觉得在model里面定义了ImageFiled,能简化MySQL存取图片。事实上在读取静态图片的时候确实很方便,只需要相对路径正确即可。
eg:
/show.html
<html>
<body>
#假装此处有静态文件夹
<img src="/static/{{image.url}}"
</body>
</html>
但是当需要读取到用户自己上传的图片的时候,路径的问题就暴露出来了。
Step1 建立一个有ImageFiled的model
image/model.py
class Image(models.Model):
image = models.ImageField(upload_to='images/',verbose_name='图片')
class Meta:
verbose_name='图片测试'
verbose_name_plural = verbose_name
step2 在setting中建立图片的上传路径
settings.py
import os
...
MEDIA_ROOT = os.path.join(BASE_DIR,'media') #图片存取的绝对路径
MEDIA_URL = '/media/' #图片存取的相对路径
...
Step 3 创建图片上传的Views
image/views.py
'''
为了做试验随便写的views
'''
from django.shortcuts import render
from django import forms
from django.views import View
from image.models import image
# Create your views here.
class ImageForm(forms.ModelForm):
class Meta:
model = image
fields = '__all__'
class ImageUploadView(View):
def get(self,request):
imageform = ImageForm
return render(request,'upload.html',{'image':imageform})
def post(self,request):
imageform = ImageForm(request.POST,request.FILES)
imageform.image = request.FILES.get('image','')
imageform.save()
return render(request,'show.html',{})
class ImageShowView(View):
def get(self,request):
images = image.objects.all()
return render(request,'show.html',{'images':images})
Step 4 配置URL
urls.py
from django.contrib import admin
from django.conf.urls import url
from image.views import ImageUploadView,ImageShowView
urlpatterns = [
url('admin/', admin.site.urls),
url('upload/$',ImageUploadView.as_view()),
url('show/$',ImageShowView.as_view())
]
Step5 Templates
这个随便写写就好了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>upload</title>
</head>
<body>
<form method="post" enctype="multipart/form-data">{% csrf_token %}
{{ image.as_p }}
<input type="submit" value="提交">
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>show</title>
</head>
<body>
<h1>这是图片↓</h1>
{% for imageobj in images %}
<img src="{{ imageobj.image.url }}">
{% endfor %}
</body>
</html>
以上的步骤都没有坑,但是当你启动好项目,满心欢喜想要看到上传的图片的时候
明明路径是对的,然鹅,Django觉得这个路径可能是别人家的
Step 6 将路径静态
试试把这个路径静态了
urls.py
from django.contrib import admin
from django.conf.urls import url
from django.conf import settings
from django.conf.urls.static import static
from image.views import ImageUploadView,ImageShowView
urlpatterns = [
url('admin/', admin.site.urls),
url('upload/$',ImageUploadView.as_view()),
url('show/$',ImageShowView.as_view())
]+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
呵,图片能够显示了。
于是继续满心欢喜地用到了正在进行的项目中
貌似有的地方还是不能用
Step7 继续查
图片也是路径诶,所以试着在urls.py加上一个匹配。
在许多博客里也找到了类似的操作,Django document中也有类似的说法
During development, you can serve user-uploaded media files from
MEDIA_ROOT
using thedjango.views.static.serve()
view.
加入了类似的匹配之后
我也不知道之前博主是怎么跑起来的。。。。可能Django的版本不同,给改了?
通过pycharm查看
'django.views.static.serve'
,发现serve就是一个函数,应该是可以用来做callback的。
from djang.views.static import serve
...
urlpatterns = [
url('admin/', admin.site.urls),
url('upload/$',ImageUploadView.as_view()),
url('show/$',ImageShowView.as_view()),
url('media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
]
又能使用了。。为了避免白高兴一场,在自己的项目里面加入试一下