python Django中不显示静态媒体图像

h5qlskok  于 2023-04-10  发布在  Python
关注(0)|答案(1)|浏览(123)

我正在开发一个在线书店应用程序。我有一个图书详细信息页面,它在一个表中显示图书信息,包括图书封面图像。我遇到了一个问题,当我运行服务器时,图像显示正确,但是团队成员无法在从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)
qqrboqgw

qqrboqgw1#

models.ImageField-这些是媒体文件,不是静态
它们受设置的影响:MEDIA_ROOT,MEDIA_URL
关于MEDIA_ROOT的文档:
将保存用户上载的文件的目录的绝对文件系统路径。
警告
MEDIA_ROOT和STATIC_ROOT必须具有不同的值。
并且媒体文件不应与静态文件混合在文件夹中。

媒体文件应该这样引用

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

这里是image-您的字段名,对于image2,它将是item.image2.url
您通过这些字段选项混合了静态媒体文件:

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)

现在一些媒体文件(image 2,image 3)可以通过MEDIA_URL访问(因为它们属于MEDIA_ROOT文件夹),一些(image)不能-因为它们属于STATIC_ROOT文件夹。您已经找到了一个解决方法-通过"{% static item.image %}"技巧引用image字段,这可以帮助克服错误的设置,但也不是正确的方法。
另外,你的队友可能会在访问“静态”文件时遇到麻烦,因为术语static被滥用了。同样,存储在ImageField s中的文件不是 static,也不是你项目的一部分。它们应该由用户上传,而不是存储在git中。如果你想共享它们-你必须以某种方式共享已经上传到本地/media/...文件夹的文件。
静态文件是/可以是这样的:

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

所以:

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

另见:

相关问题