首页 > 解决方案 > 来自 DRF 的图像未在反应 js 中加载

问题描述

我的 react js 应用程序不会从我的 DRF 加载任何图像。我很难解决这个问题,但我找不到解决方案。

在我的反应应用程序中,我正在从中获取数据https://randomuser.me/api/?results=20'(将结果映射到“<img..”等),并加载获取的图像<img src="https://...." alt='image'>并立即显示它们。但是当我获取我的 DRF api 时,我会超时。

<img className='user-avatar-settings' src={ this.state.photo} alt='user-avatar' />this.state.photo在 哪里https://127.0.0.1:8001/media/user_avatar/user_3.jpg

铬在说:127.0.0.1:8001/media/user_avatar/user_3.jpg:1 GET https://127.0.0.1:8001/media/user_avatar/user_3.jpg net::ERR_TIMED_OUT过一会儿。

*) 第一个网址不正确,第二个网址不正确。*) 单击正确的 url 时,图像未加载(单击重定向到新的 Chrome 选项卡,所以我不在应用程序之外)。*) 我首先需要退出并重新启动 Django 服务器,然后图像会立即加载到 Chrome 选项卡中 - 但不是在我的 react 应用程序中。 即使是带有图像 url 的 GET 请求也会遇到该超时。 这是一个例子:

componentDidMount() {

    fetch(`https://127.0.0.1:8000/api/userpic/${localStorage.getItem('id')}/`)
      .then(response => {
        if (response.status === 200) {
          //response.data from django view "userpic" returns relative path to /media, so the rest of the path needs to be added
          this.setState({ photo: 'https://127.0.0.1:8000' + response.data })
        } else { alert('NOT LOADED') }
      })

    if (this.state.errors && (this.mapErrors() !== undefined)) {
      // Maps errors to text for UI
      return <ul>{this.mapErrors()}</ul>
    }
    if (this.state.isLoading) {
      //A loading screen
      return <Splash />
    }

  }

  render() {
       ....

       <img className='user-avatar-settings' src={this.state.photo} alt='user-avatar' />

这是通过 url ".../userpic/userid/" 调用的 django 视图

class UserUploadImage(RetrieveUpdateAPIView):
    #permission_classes = (IsLoggedInUser, )
    parser_classes = [MultiPartParser, ]

    serializer_class = AvatarSerializer
    queryset = User.objects.all()

    def get(self, request, pk, *args, **kwargs):
        user = User.objects.get(id=pk)
        if not user.is_authenticated:
            return HttpResponse('Unauthorized', status=401)
        serializer = AvatarSerializer(user, many=False)
        return Response(serializer.data)

这不取决于那一个特定的图像。react js 中没有显示来自后端 /media/ 文件夹的图像 - 只有来自浏览器的一个小“占位符”图像(迷你图像)。

这对某人来说可能听起来很熟悉吗?有人知道会出什么问题吗?

据我研究,后端很好:

设置.py:

MEDIA_ROOT = os.path.join(BASE_DIR,'media')
MEDIA_URL = '/media/'

#location where django collect all static files
STATIC_ROOT = os.path.join(BASE_DIR,'static')# location where you will store your static files
STATICFILES_DIRS = [os.path.join(BASE_DIR,'static')]
STATIC_URL = '/static/'


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',
    'corsheaders',
    'sslserver',
    'posts',
    'rest_framework',
    'rest_auth',
    'rest_framework_simplejwt.token_blacklist',
]
SITE_ID = 1

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

网址.py:

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

urlpatterns = [
    path('admin/', admin.site.urls),
    #path('accounts/', include('django.contrib.auth.urls')),
    path('api/', include('posts.api.urls')),
] 
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

正如我已经描述的那样,图像保存在@backend 并且可调用,但不在 react js 应用程序中。

是否有一种 webpack-config 解决方法?请放弃您能想象的任何解决方案..!我会尝试任何事情

标签: reactjsdjangodjango-rest-framework

解决方案


尝试以下操作:

在 settings.py 中:

STATIC_URL = '/static/'
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))

if DEBUG:
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, 'static'), #Your bundle.js path
    ]
else:
    STATIC_ROOT = os.path.join(BASE_DIR,'static')

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

在开发时使用 DEBUG = True,在生产中使用 DEBUG = False。在后者中,您应该执行 python manage.py collectstatic

在 ursl.py 中:

from django.views.static import serve

urlpatterns = [
    re_path(r'^media/(?P<path>.*)$', serve,{'document_root': settings.MEDIA_ROOT}),
    re_path(r'^static/(?P<path>.*)$', serve,{'document_root': settings.STATIC_ROOT}),
]

推荐阅读