【问题标题】:Can't display photo using imageField in models.py of my Django app?无法在我的 Django 应用程序的 models.py 中使用 imageField 显示照片?
【发布时间】:2015-02-15 17:48:03
【问题描述】:

在我的 Django PhotoViewer 应用程序的 models.py 中,我为我的 Photo 类定义了一个 imageField,用于在网站上显示图像。我通过 Django 管理页面上传了几张照片,但没有一张显示出来。我确实在本地 /static/images 文件夹中看到所有这些照片。但是当我转到我的照片索引(照片列表页面):127.0.0.1:8000:photoViewer/photos 时,我看到的是下面的页面:

models.py:

from django.db import models
#photoViewer/: (index) photostream (list all photos) 
class Photo (models.Model):
    photo_title = models.CharField(max_length=200)
    #how to retrieve from metadata of file?
    date_taken = models.DateField('date taken', default=None, blank=True, null=True)
    photo_img = models.ImageField(upload_to = "images/", default= "")
    def __str__(self):              # __unicode__ on Python 2
        return self.photo_title

photoViewer/urls.py

from django.conf.urls import patterns, url

from photoViewer import views

urlpatterns = patterns('',
    #  "photoViewer/photos" 
    url(r'^photos/$', views.IndexView.as_view(), name='index'),

    #  "photoViewer/photos/5/"
    url(r'^photos/(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),

    #  "photoViewer/albums/"
    # Display list of albums
    url(r'^albums/$', views.AlbumsIndexView.as_view(), name='albumsIndex'),

    #  "photoViewer/albums/1"
    # Display photos for a given album
    url(r'^albums/(?P<pk>\d+)/$', views.AlbumDetailView.as_view(), name='albumDetail'),

    url(r'^test/$', views.TemplateTestView.as_view(), name='templateTest'),


)

photoViewer/views.py

from django.shortcuts import get_object_or_404, render
from django.http import Http404, HttpResponse, HttpResponseRedirect
from django.template import RequestContext, loader 
from photoViewer.models import Photo, Album
from django.core.urlresolvers import reverse
from django.views import generic

# Create your views here.

class TemplateTestView (generic.ListView):
    model = Photo
    template_name = 'photoViewer/test.html'

class IndexView(generic.ListView):
    #By default: Uses <app name>/<model name>_detail.html
    #as template
    template_name = 'photoViewer/photo_index.html'
    context_object_name = 'latest_photo_list'
    def get_queryset(self):
        return Photo.objects.order_by('-date_taken')[:5]

class DetailView(generic.DetailView):
    model = Photo
    #By default: Uses <app name>/<model name>_detail.html
    #Unless specified by template_name
    template_name = 'photoViewer/photo_detail.html'
    #context_object_name = <new name> 


class AlbumsIndexView(generic.ListView):
    template_name = 'photoViewer/albums_index.html'
    context_object_name = 'latest_albums_list'
    def get_queryset(self):
        return Album.objects.order_by('-date_created')[:5]


class AlbumDetailView(generic.DetailView):
    model = Album
    template_name = 'photoViewer/albums_detail.html'

photoViewer/templates/photoViewer/photo_detail.html(照片详情页面模板):

<h1>Photo Detail</h1>
<li>{{ photo.photo_title }}</li>
<li>{{ photo.date_taken }}</li>
<img src="/static/{{ photo.photo_img }}" alt={{ photo.photo_title }}>

<h2>Albums Association</h2>
{% if photo.album_set.all %}
<ul>
    {% for album in photo.album_set.all %}
        <li>{{ album.album_title }}</li>


        <!-- <li><a href="{% url 'photoViewer:detail' photo.id %}">{{ photo.photo_title }}</a>    {{ photo.date_taken }} </li>
 -->
    {% endfor %}
</ul>
{% else %}
    <p>This Photo is Not in Any Album</p>
{% endif %}

我安装了最新版本的pillow

【问题讨论】:

  • 您的视图是什么样的?您的浏览器试图加载什么 url?它会返回 404、401 还是其他?
  • 需要查看模板以及如何访问那里的图像字段。
  • 刚刚更新了我的问题以包含 urls.py、views.py 和模板文件
  • 404 控制台输出在网络选项卡中的外观如何?您的 MEDIA_URL 设置是什么?在管理站点,在更改模型形式时,您可以单击链接并在浏览器中查看图像吗?
  • 我已将 img src 从“/static/{{ photo.photo_img }}”更改为“/media/{{ photo.photo_img }}”,现在可以正常工作了!我注意到在管理站点中,照片链接指向127.0.0.1:8000/media/images,而不是我想象的 /static。您通过管理员上传的所有照片最终都在 /media 而不是 /static 中吗?那么如何将图片放入/static 并访问/​​static 媒体呢?

标签: python django


【解决方案1】:

每当您使用模型对象显示图像时,您都需要使用object.photo_img.url 来访问图像路径。但在此之前,请确保 photo_img 不包含空字符串。

[已编辑] 您的开发服务器将不会提供图像,除非您按照 Django 文档中的说明将静态 url 添加到 urls.py 条目中

urlpatterns = patterns('',
    # ... the rest of your URLconf goes here ...
)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_ROOT, document_root=settings.MEDIA_ROOT)

参考:https://docs.djangoproject.com/en/1.7/howto/static-files/#serving-static-files-during-development

【讨论】:

  • 您能详细说明一下吗?我刚刚在原始问题中添加了更多文件信息。我们把“object.photo_img.url”放在哪里?我尝试用 object.photo_img.url 和 photo.photo_img.url 替换“photo_detail.html”中的 src 标签值。但仍然没有显示图像
  • photo_img 包含“images/mountain_wallpapers.jpg”,是我的静态文件夹中图片的正确路径
  • 请注意,静态文件和媒体文件不同,维护方式也不同。我认为您没有为您的开发服务器添加任何 URL。请看看这个docs.djangoproject.com/en/1.7/howto/static-files/…。您需要为静态根目录和媒体根目录添加 2 个 URL
  • 好的,我已经完成了你发布的内容。当我在“templates/photoViewer/photo_detail.html”页面中硬编码图像 url 时,它正确显示了图像:
  • 但是当我引用 photo.photo_img 字段时,它无法再次正确显示图像。 。我也试过了,photo.photo_img.url,同样的事情
【解决方案2】:

在模板中使用 {{STATIC_URL}} 而不是硬编码“/static/”。

设置 STATIC_ROOT 以在您的开发和服务器环境中正确地提供静态文件。

【讨论】:

  • 不要使用 STATIC_URL,而是使用 {% load staticfiles %}{% static 'myrelative/path/to/file' %}。使用STATIC_URL 是不灵活的,尤其是关于使用的协议和静态文件映射,而不仅仅是使用文件名的前缀。
【解决方案3】:

试试这个并在 SETTINGS.py 中进行更改

STATIC_URL = '/static/'

MEDIA_ROOT = '/home/subhanshu/mysite/static/'     #put the absolute path 

MEDIA_URL =   '/home/subhanshu/mysite/static/'    #put the absolute path

STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)

并像这样对模板进行更改:

{% for CLASSNAME in Object %}
<img src="/static/{{CLASSNAME.CLASS_OBJECT}}" />
{% endfor %}

如果你想展示一些静态图片,你可以使用这个:

<img src="{% static 'img/example.jpg' %}">

【讨论】:

    【解决方案4】:

    我总是这样配置我的开发环境:

    Django - 用于处理请求,nginx - 用于提供静态和媒体。

    我还建议您为开发站点设置域。

    您需要像这样设置 STATIC_ROOT 和 MEDIA_ROOT:

    # settings.py
    import os
    SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
    STATIC_ROOT = os.path.join(SITE_ROOT, 'static')
    MEDIA_ROOT =  os.path.join(SITE_ROOT, 'static')
    

    注意:不要把你的静态文件放到STATIC_ROOT!在每个应用程序中创建静态文件夹,然后使用collectstatic 命令。它将遍历所有已安装的应用程序并将所有静态从它复制到 STATIC_ROOT。但是您需要在添加或编辑某些文件后运行此命令。如果你想经常编辑它们(对于 js 和 css 文件),只需使用 collectstatic 命令的“-l”选项 - 它会创建链接而不是副本。

    你应该这样做吗? - 默认的 django 开发服务器一次只能处理一个请求。例如:如果页面上有 10 个文件,一个文件请求时间是 200 毫秒,那么加载一个页面大约需要 2000 毫秒。 Nginx 可以一次处理任意数量的请求 - 总页面加载时间约为 200 毫秒。当您甚至无法在页面重新加载时眨眼时,这真是太好了。另一个好处 - 你不会在 django 请求日志中看到任何无用的请求。

    使用上面显示的设置,django 会自动将文件上传到 MEDIA_ROOT。

    Nginx 安装很简单:sudo apt-get install nginx

    示例 nginx 配置:

    server {
        listen  80;
    
        server_name myserver.com; #you can set any domain name you like in /etc/hosts
        #just add line 127.0.0.1    myserver.com into it
    
        access_log  /var/logs/nginx/myserver.log;
        error_log   /var/logs/nginx/myserver.log;
    
        location / {
            proxy_pass http://127.0.0.1;
        }
    
        location /static {
            autoindex off;
            alias /var/www/myserver/static/; # put here path to you static root
            if ($query_string) {
                expires max;
            }
        }
    
        location /media {
            alias /var/www/myserver/media/; # put here path to you media root
            # if asset versioning is used
            if ($query_string) {
                expires max;
            }
        }
    
       if ($host ~* www\.(.*)) {
          set $host_without_www $1;
           rewrite ^(.*)$ http://$host_without_www$1 permanent;
        }
    
    }
    

    把nginx配置放到:/etc/nginx/sites-enabled/you_file_name 之后不要忘记重新加载 nginx 配置 sudo nginx -t #检查配置 sudo 服务 nginx 重新加载 sudo service ngixn 重启

    如果您在页面上看不到图片:

    1. 在源码中查找url
    2. 尝试直接通过浏览器打开
    3. 检查 nginx 日志

    我希望我的小建议能帮助你在艰苦的开发者生活中。 ;-)

    【讨论】:

      【解决方案5】:

      首先您应该注意,静态文件和媒体文件是两个不同的东西。静态文件与应用程序一起部署,用于静态内容(css、js、样式化站点的图像)。媒体文件被上传并用于模型等。

      接下来:默认情况下,django 开发服务器不提供媒体文件。所以你应该为他们服务。

      为了显示您的图像,您应该在这样的模板代码中使用:

      <img src="{{ photo.photo_img.url }}" alt={{ photo.photo_title }}>
      

      您不必(也不应该)自己为静态或媒体文件添加前缀,django 会根据您的设置中的STATIC_URLMEDIA_URL 处理它。

      【讨论】:

      • 我已经使用管理员上传了一些 .jpeg 图片,它们最终都在我的 static/ 目录中。我的目的是创建一个个人照片组合网站,用户可以在其中上传照片并让它们显示在外部网站上
      • 如果它们最终位于静态目录中,则说明您的配置错误,或者您使用的是非常过时的 django。从您的 settings.py 文件中显示您的 STATIC_ROOT 和 MEDIA_ROOT。
      • MEDIA_ROOT = os.path.join(os.path.dirname(file), '..', 'static').replace('\\',' /')
      • 我的 STATIC_ROOT 没有设置
      • 所以,如果我在托管个人照片组合网站,只有管理员(我)可以将照片上传到网站供其他人查看,这些照片应该是静态的还是媒体内容?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      • 1970-01-01
      • 2020-03-03
      • 1970-01-01
      • 1970-01-01
      • 2011-02-06
      相关资源
      最近更新 更多