Все статические активы возвращаются как «404 (Не найдено)» в приложении Django / React - PullRequest
0 голосов
/ 28 июня 2018

Мое приложение находится на пути к серверу /home/myapp/.

Статические активы находятся на /home/myapp/src/static/, когда выполняется python manage.py collectstatic.

Копирует активы из /home/myapp/src/assets/.

Я пробовал с DEBUG и True, и False.

Когда я перехожу к веб-приложению на https://test.example.com, оно говорит мне, что все активы, которые находятся на /home/mpapp/src/assets/, равны 404 (Not Found), несмотря на наличие файлов.

Кроме того, мой веб-сервер настроен на 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 wsgi, где manage.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

Моя структура каталогов выглядит следующим образом, основанная на Two 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_ROOT и STATIC_URL на фактический путь /home/myapp/src/static/, который ничего не сделал.

Немного озадачен тем, как решить эту проблему, и вопросы SO, которые я рассмотрел, не устранили проблему.

1 Ответ

0 голосов
/ 28 июня 2018

Что ж, я могу начать загрузку, выполнив в 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

Это работает, но, как говорится, разделы называются «Обслуживание статических файлов во время разработки» ... Я делаю это для производства.

...