如何将上传的文件保存到模型并在模板中提供?

How to save uploaded files to models and serve them in templates?

我一直在关注 django 2 官方教程,但我对如何处理图像和上传的文件有点困惑。

我有一个包含几个应用程序的项目。我们将项目命名为 myProj,将应用程序命名为 myApp。 myApp 中有一个名为 myModel 的模型,它有一个图像字段 myImage。 这是我的模型:

from django.db import models

class myModel(models.Model):
    myImage = models.ImageField(upload_to='myApp_images')

这是我的模板:

<img src="{{ n.image }}"></img>

这是我的看法

from django.shortcuts import get_object_or_404, render
from .models import myModel

def index(request):
    n = myModel.objects[0]
    context = {
        'n': n,
        }
    return render(request, 'myModel/index.html', context)

这是我的设置:(我认为相关的部分)

INSTALLED_APPS = [
    'news.apps.myModelConfig',
    'django.contrib.staticfiles',
]

MEDIA_URL = '/media/'

MEDIA_ROOT = '/home/aran/myfiles/projects/futureCoin/media/'

这是我的myProject/urls.py:

from django.contrib import  admin
from django.urls import include, path
from django.conf import settings
from django.conf.urls.static import static


urlpatterns = [
    path('myModel/', include('myModel.urls')),
    path('admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

所以我通过 django 管理站点创建了一个模型实例。 这是之后的目录树(我删除了pycache):

.
├── myProject
│   ├── __init__.py
│   ├── models.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── media
│   └── myModel_images
│       └── myImage.jpeg
├── myModel
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   ├── models.py
│   ├── static
│   │   └── myModel
│   │       ├── images
│   │       │   └── bg.jpg
│   │       └── style.css
│   ├── templates
│   │   └── myModel
│   │       └── index.html
│   ├── tests.py
│   ├── urls.py
│   └── views.py

现在的问题是,当我尝试打开索引页时,图像没有显示,因为它的 url 是:http://127.0.0.1:8000/myModel/myModel_images/myImage.jpg 但是,如果我手动打开 url:http://127.0.0.1:8000/media/myModel_images/myImage.jpg,我会看到正确的图像。谁能帮我了解问题出在哪里以及如何解决?对我的代码的任何其他反馈也将不胜感激。

当我执行 n.image 时会发生什么,为什么它给了我一个 url 而不是一个错误的 url?

完全没有错url。那是因为 n.image returns 像 /path/to/image.jpg 这样的图像的 url 路径与您在 ImageField upload_to

中设置的方式完全相同
myImage = models.ImageField(upload_to='myApp_images')

默认情况下,这将以您的 url 地址为前缀,并变为 127.0.0.1:8000/path/to/image.jpg。如您所见,它错过了 settings.MEDIA_URL 中提供的 /media/,您的所有图像都已本地化。

所以现在通过使用 {{ n.image.url}},你实际上是从你的设置配置中调用它,你的 MEDIA_URL /media/ 将被添加为前缀并变成 /media/path/to/image.jpg 前缀url127.0.0.1:8000

要修复它,请在您的模板中使用 {{instance.field.url}}

访问图像 url

尝试:

<img src="{{ n.image.url }}"></img>

而不是

<img src="{{ n.image }}"></img>