在Django / React应用中,所有静态资产返回为“ 404(未找到)”

时间:2018-06-28 16:56:51

标签: django reactjs apache gunicorn

我的应用程序位于服务器路径/home/myapp/上。

执行/home/myapp/src/static/时,静态资产位于python manage.py collectstatic处。

它从/home/myapp/src/assets/复制资产。

我已经尝试DEBUGTrue都使用False

当我导航到位于https://test.example.com的Web应用程序时,它告诉我尽管文件在那里,但位于/home/mpapp/src/assets/的所有资产都是404 (Not Found)

此外,我的Web服务器设置是Apache,并带有Gunicorn的反向代理。我使用gunicorn wsgi为应用程序提供服务,而127.0.0.1:8000为应用程序提供服务,{Apache是​​ProxyPass的所在地。我已经针对全新的Django应用程序进行了测试,并且此设置可以正确地为其提供服务,因此它不应该是配置Apache和Gunicorn的方式。

我一直在做的是:

1)npm start来编译React前端资产

2)python manage.py collectstatic将资产移动到/static/

3)在gunicorn wsgimanage.py所在的地方运行wsgi.py

一些代码会有所帮助。这是我的settings.py

import os
import sys
import json
import datetime

from unipath import Path
from django.core.exceptions import ImproperlyConfigured

# Import JSON file 
print(Path(__file__))
with open('./config/config.json') as f:
    s = json.loads(f.read())

def get_settings(settings, s=s):
    try:
        return s[settings]
    except KeyError:
        error_msg = 'Set the {0} environment vaiable'.format(settings)
        raise ImproperlyConfigured(error_msg)


# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = Path(__file__).ancestor(2)


# Quick-start development settings - unsuitable for production

# SECURITY WARNING: keep the secret key used in production secret! 
SECRET_KEY = get_settings('SECRET_KEY')


ALLOWED_HOSTS = [
    '*',
]

# Application definition

INSTALLED_APPS = [
    # Base packages
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Third party packages
    'rest_framework',
    'rest_framework_jwt',
    'webpack_loader',
    'tinymce',

    # Local packages
    'authentication',
    'documents',
    'contact',
    'home',
    'results',
    'users'
]

MIDDLEWARE = [
    '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',
]

ROOT_URLCONF = 'config.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]


# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = get_settings('DEBUG')

WSGI_APPLICATION = 'wsgi.application'


# Password validation
AUTH_USER_MODEL = 'authentication.User'

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# REST Framework settings
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
         'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
}


# DRF JWT token settings
JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
    'JWT_ALLOW_REFRESH': True,
}


# Webpack settings
WEBPACK_LOADER = {
    'DEFAULT': {
        'BUNDLE_DIR_NAME': 'bundles/',
        'STATS_FILE': os.path.join(BASE_DIR, './config/webpack-stats.json'),
    }
}


STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'assets'),
)

STATIC_ROOT = os.path.join(BASE_DIR, 'static')

# Static files (CSS, JavaScript, Images)

STATIC_URL = '/static/'


# Internationalization

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'America/Los_Angeles'

USE_I18N = True

USE_L10N = True

USE_TZ = False


# EMAIL SETTINGS

EMAIL_HOST = get_settings('EMAIL_HOST')

EMAIL_HOST_USER = get_settings('EMAIL_HOST_USER')

EMAIL_HOST_PASSWORD = get_settings('EMAIL_HOST_PASSWORD')

EMAIL_PORT = get_settings('EMAIL_PORT')

EMAIL_USE_TLS = True

我的目录结构如下所示,基于两个Scoops:

testapp
    assets
        bundles
            css
                app.e1c352f1.css
            js
                vendor.s63d4f.js
                manifrest.5fd4g.js
                app.dsr5h4.js
        css
            bootstrap.css
        img
        scss
    config
         config.json
         settings.py
         urls.py
         webpack.config.js
    react
         index.jsx
    static
         admin
         bundles
             css
                app.e1c352f1.css
             js
                vendor.s63d4f.js
                manifrest.5fd4g.js
                app.dsr5h4.js
         css
             bootstrap.css
         img
         rest_framework
         scss
    templates
         index.html
    manage.py
    wsgi.py

此外,如果我的urls.py可能相关:

from django.conf.urls import url, include
from django.contrib import admin
from django.views.generic.base import TemplateView

from home.views import GetHomeAPIView

    urlpatterns = [
        # Admin URL
        url(r'^admin', admin.site.urls),

        # API authentication entry point   
        url(r'^api/auth/', include('authentication.urls', namespace='signin')),

        # API /home entry point   
        url(r'^api/home/', GetHomeAPIView.as_view(), name='home'),

        # API /contact entry point   
        url(r'^api/contact/', include('contact.urls', namespace='contact')),

        # API /contact entry point   
        url(r'^api/users/', include('users.urls', namespace='users')),

        # Any requets that come through serve the index.html
        url(r'^$', TemplateView.as_view(template_name='index.html')),
    ]

所以不确定100%该怎么做。

我尝试将STATIC_ROOTSTATIC_URL都更改为没有任何作用的实际路径/home/myapp/src/static/

对于如何解决此问题有些困惑,我所审查的SO问题并未解决该问题。

1 个答案:

答案 0 :(得分:1)

好吧,我可以通过在urls.py中执行以下操作来开始加载:

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

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

也可以在这里阅读。

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

它正在工作,但是可以这么说,这些部分称为“在开发过程中提供静态文件” ...我正在为生产而做。