Django model.ImageFiled 图片的上传及显示

做项目中的一个坑。。
本来觉得在model里面定义了ImageFiled,能简化MySQL存取图片。事实上在读取静态图片的时候确实很方便,只需要相对路径正确即可。
eg:

/show.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

这个随便写写就好了




    
    upload


{% csrf_token %} {{ image.as_p }}



    
    show


这是图片↓

{% for imageobj in images %} {% endfor %}
以上的步骤都没有坑,但是当你启动好项目,满心欢喜想要看到上传的图片的时候
Django model.ImageFiled 图片的上传及显示_第1张图片
Django model.ImageFiled 图片的上传及显示_第2张图片

明明路径是对的,然鹅,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)
Django model.ImageFiled 图片的上传及显示_第3张图片

呵,图片能够显示了。
于是继续满心欢喜地用到了正在进行的项目中


Django model.ImageFiled 图片的上传及显示_第4张图片

Django model.ImageFiled 图片的上传及显示_第5张图片
hehe

貌似有的地方还是不能用

Step7 继续查

图片也是路径诶,所以试着在urls.py加上一个匹配。
在许多博客里也找到了类似的操作,Django document中也有类似的说法


Django model.ImageFiled 图片的上传及显示_第6张图片
CSDN上的一些博客中的操作

During development, you can serve user-uploaded media files from MEDIA_ROOT using the django.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.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
]
Django model.ImageFiled 图片的上传及显示_第7张图片

又能使用了。。为了避免白高兴一场,在自己的项目里面加入试一下


Django model.ImageFiled 图片的上传及显示_第8张图片

Django model.ImageFiled 图片的上传及显示_第9张图片

为什么图片能显示了想着还是那么难受。

两个同样方式创建的项目,在step6同样的操作一个能正常显示出数据库中的图片,一个却不能。。

你可能感兴趣的:(Django model.ImageFiled 图片的上传及显示)