【问题标题】:Static media images are not displaying in Django静态媒体图像未在 Django 中显示
【发布时间】:2021-06-24 06:04:11
【问题描述】:

我正在开发一个在线书店应用程序。我有一个书籍详细信息页面,它在表格中显示书籍信息,包括书籍封面图像。我在运行服务器时遇到图像正确显示的问题,但是团队成员在从 Github 提取我的代码后无法显示图像。

所有书籍模板:

{%  extends 'bookstore/main.html' %}
{% load crispy_forms_tags %}
{% load static %}
from .models import Product

{% block content %}
  <div class="container">  
      <p>
        <h1 style="text-align:center;color:green;"> 
            GeekText Complete List of Books<br>
        </h1>

        <h3 style="text-align:center;color:green;">
            Click the Book Name for More Details
        </h3>
      </p>
      
    <div class="container">
      <div class="col-md-12">
        <table id="myTable" class="table table-striped tablesorter">  
            <thead>  
                <tr>  
                    <th scope="col">ID #</td>  
                    <th scope="col">Book Title</td>  
                    <th scope="col">Genre</th>
                    <th data-sorter="false" scope="col">Cover Image</td>  
                    <th scope="col">Author</td> 
                </tr>  
            </thead>  
              
            <tbody>  
                {% for item in items %}
                <tr>  
                    <td scope="row">{{ item.id }}</td>   
                    <td><a href="{% url 'book_details_with_pk' id=item.id %}">{{ item.name }}</a></td>   
                    <td>{{ item.genre }}</td>
                    <td><img src="{% static item.image %}" width="75" height="100"/></td> 
                    <td>{{ item.author }}</td>    
                    
                    <td><a href="{% url 'addtocart' item.id %}" class="btn btn-primary">Add To Cart</a>
                </tr>  
                {% endfor %}
            </tbody>  
        </table>
        {% endblock %}
      </div>  
    </div> 
    </div> 

views.py

from django.shortcuts import render, redirect
from django.db.models import Q
from django.views.generic import TemplateView, ListView, View
from .models import Product
from .models import Author
from .models import Genre
from .models import CartProduct
from .models import Cart
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

def all_books(request, id=None):
    item = Product.objects.get(id=id)
    context = {
        'items': Product.objects.all().order_by('id'),
        'id': item.id, 
        'name': item.name,
        'cover': item.image,
        'author': item.author,
    }
    
    return render(request,'bookstore/all_books.html', context)

urls.py

from django.urls import path
from . import views
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('all_books/', views.all_books, name="all_books"),
    path('book_details/', views.book_details, name="book_details"),
    path(r'^book_details/(?P<id>\d+)/$', views.book_details, name="book_details_with_pk"),
    path('books/', views.books, name="books"),
    path(r'^book_author/(?P<id>\d+)/$', views.book_author, name="book_author"),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'crispy_forms',
    'apps.users',
    'apps.bookstore',
    'django_filters',
]

STATIC_URL = '/static/'
MEDIA_URL = '/media/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

models.py

class Product(models.Model): # model to create table on database products

    genre = models.ForeignKey(Genre,related_name='products',on_delete=models.CASCADE)
    author = models.ForeignKey('Author',related_name='authors',on_delete=models.CASCADE)
    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, db_index=True)
    image = models.ImageField(upload_to='static/media',blank=True)
    image2 = models.ImageField(upload_to='media/%Y/%m/%d',blank=True)
    image3 = models.ImageField(upload_to='media/%Y/%m/%d',blank=True)
    publisher = models.CharField(max_length=100, db_index=True)
    release_date = models.DateTimeField(null=True)
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    created = models.DateTimeField(default=timezone.now)
    updated = models.DateTimeField(auto_now=True)

【问题讨论】:

  • MEDIA_ROOT = os.path.join(BASE_DIR, 'static/images') 将此行添加到settings.py中试试看是否可行

标签: python django django-staticfiles django-media


【解决方案1】:

models.ImageField - 这些是媒体文件,而不是静态。

他们通过设置获得affected:MEDIA_ROOT, MEDIA_URL

docs 对 MEDIA_ROOT 的评价:

将保存用户上传的文件的目录的绝对文件系统路径。

警告

MEDIA_ROOT 和 STATIC_ROOT 必须有不同的值。

并且媒体文件不应与文件夹中的静态文件混合。

媒体文件应该这样引用

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

这里是image - 你的字段名,对于image2,它将是item.image2.url

您通过这些字段选项混合了 static 和 media 文件:

image = models.ImageField(upload_to='static/media',blank=True)
image2 = models.ImageField(upload_to='media/%Y/%m/%d',blank=True)
image3 = models.ImageField(upload_to='media/%Y/%m/%d',blank=True)

现在一些媒体文件(image2、image3)可以通过MEDIA_URL访问(因为它们属于MEDIA_ROOT文件夹),一些(image)不是 - 因为它们属于STATIC_ROOT 文件夹。您找到了一种解决方法 - 您通过 "{% static item.image %}" 技巧引用 image 字段,这有助于克服错误的设置,但也不是正确的方法。

此外,您的队友可能在访问“静态”文件时遇到问题,因为术语 static 被滥用。同样,存储在ImageFields 中的文件不是静态,也不属于您的项目。它们应该由用户上传,从不存储在 git 中。如果您想共享它们 - 您必须以某种方式共享已上传到本地 /media/... 文件夹的文件。

静态文件是/可以是这样的:

  • favicon.ico
  • main.css
  • robots.txt
  • popup.js
  • top_banner.jpg

所以:

  • 将upload_to 更改为image 字段
  • 将已上传的文件移动到新文件夹(media 文件夹下),更新 db 中的文件路径
  • 将您在模板中引用这些媒体文件的方式修复为...image.url

另见:

【讨论】:

    猜你喜欢
    • 2021-10-12
    • 2017-07-08
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-18
    相关资源
    最近更新 更多