Commit b129f51c by Calen Pennington

Make collectstatic compile .coffee files, and preserve the askbot workflow using guard

parent 45dcd1ee
source :rubygems source :rubygems
gem 'guard', '~> 1.0.3' gem 'guard', '~> 1.0.3'
gem 'guard-process', '~> 1.0.3'
gem 'guard-coffeescript', '~> 0.6.0'
gem 'sass', '3.1.15' gem 'sass', '3.1.15'
gem 'guard-sass', :github => 'sikachu/guard-sass'
gem 'bourbon', '~> 1.3.6' gem 'bourbon', '~> 1.3.6'
gem 'libnotify', '~> 0.7.2' gem 'libnotify', '~> 0.7.2'
gem 'ruby_gntp', '~> 0.3.4' gem 'ruby_gntp', '~> 0.3.4'
gem 'guard-rake', '0.0.5'
GIT
remote: git://github.com/sikachu/guard-sass.git
revision: 2a646996d7fdaa2fabf5f65ba700bd8b02f14c1b
specs:
guard-sass (0.6.0)
guard (>= 0.4.0)
sass (>= 3.1)
GEM GEM
remote: http://rubygems.org/ remote: http://rubygems.org/
specs: specs:
bourbon (1.3.6) bourbon (1.3.6)
sass (>= 3.1) sass (>= 3.1)
coffee-script (2.2.0)
coffee-script-source
execjs
coffee-script-source (1.3.3)
execjs (1.3.2)
multi_json (~> 1.0)
ffi (1.0.11) ffi (1.0.11)
guard (1.0.3) guard (1.0.3)
ffi (>= 0.5.0) ffi (>= 0.5.0)
thor (>= 0.14.6) thor (>= 0.14.6)
guard-coffeescript (0.6.0) guard-rake (0.0.5)
coffee-script (>= 2.2.0) guard
guard (>= 0.8.3) rake
guard-process (1.0.3)
ffi (~> 1.0.9)
guard (>= 0.4.2)
spoon (~> 0.0.1)
libnotify (0.7.2) libnotify (0.7.2)
multi_json (1.3.5) rake (0.9.2.2)
ruby_gntp (0.3.4) ruby_gntp (0.3.4)
sass (3.1.15) sass (3.1.15)
spoon (0.0.1)
thor (0.15.2) thor (0.15.2)
PLATFORMS PLATFORMS
...@@ -41,9 +22,7 @@ PLATFORMS ...@@ -41,9 +22,7 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
bourbon (~> 1.3.6) bourbon (~> 1.3.6)
guard (~> 1.0.3) guard (~> 1.0.3)
guard-coffeescript (~> 0.6.0) guard-rake (= 0.0.5)
guard-process (~> 1.0.3)
guard-sass!
libnotify (~> 0.7.2) libnotify (~> 0.7.2)
ruby_gntp (~> 0.3.4) ruby_gntp (~> 0.3.4)
sass (= 3.1.15) sass (= 3.1.15)
require 'bourbon' guard :rake, :task => :collectstatic, :run_on_all => true, :run_on_start => true do
watch(%r{^static/.+(.scss|.coffee)$})
# Helper method
def production?
@@options[:group].include? 'production'
end
guard :coffeescript, :name => :jasmine, :input => 'templates/coffee/spec', :all_on_start => production?
guard :coffeescript, :input => 'templates/coffee/src', :noop => true
guard :process, :name => :coffeescript, :command => "coffee -j static/js/application.js -c templates/coffee/src" do
watch(%r{^templates/coffee/src/(.+)\.coffee$})
end
if production?
guard :sass, :input => 'templates/sass', :output => 'static/css', :style => :compressed, :all_on_start => true
else
guard :sass, :input => 'templates/sass', :output => 'static/css', :style => :nested, :line_numbers => true
end end
...@@ -153,7 +153,7 @@ MANAGERS = ADMINS ...@@ -153,7 +153,7 @@ MANAGERS = ADMINS
# Static content # Static content
STATIC_URL = '/static/' STATIC_URL = '/static/'
ADMIN_MEDIA_PREFIX = '/static/admin/' ADMIN_MEDIA_PREFIX = '/static/admin/'
STATIC_ROOT = ENV_ROOT / "staticfiles" # We don't run collectstatic -- this is to appease askbot checks STATIC_ROOT = ENV_ROOT / "staticfiles"
# FIXME: We should iterate through the courses we have, adding the static # FIXME: We should iterate through the courses we have, adding the static
# contents for each of them. (Right now we just use symlinks.) # contents for each of them. (Right now we just use symlinks.)
...@@ -217,7 +217,7 @@ SIMPLE_WIKI_REQUIRE_LOGIN_EDIT = True ...@@ -217,7 +217,7 @@ SIMPLE_WIKI_REQUIRE_LOGIN_EDIT = True
SIMPLE_WIKI_REQUIRE_LOGIN_VIEW = False SIMPLE_WIKI_REQUIRE_LOGIN_VIEW = False
################################# Jasmine ################################### ################################# Jasmine ###################################
JASMINE_TEST_DIRECTORY = PROJECT_ROOT + '/templates/coffee' JASMINE_TEST_DIRECTORY = PROJECT_ROOT + '/static/coffee'
################################# Middleware ################################### ################################# Middleware ###################################
# List of finder classes that know how to find static files in # List of finder classes that know how to find static files in
...@@ -266,36 +266,49 @@ STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage' ...@@ -266,36 +266,49 @@ STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage'
PIPELINE_CSS = { PIPELINE_CSS = {
'application': { 'application': {
'source_filenames': ['css/application.scss'], 'source_filenames': ['sass/application.scss'],
'output_filename': 'css/application.css', 'output_filename': 'css/application.css',
}, },
'marketing': { 'marketing': {
'source_filenames': ['css/marketing.scss'], 'source_filenames': ['sass/marketing.scss'],
'output_filename': 'css/marketing.css', 'output_filename': 'css/marketing.css',
}, },
'marketing-ie': { 'marketing-ie': {
'source_filenames': ['css/marketing-ie.scss'], 'source_filenames': ['sass/marketing-ie.scss'],
'output_filename': 'css/marketing-ie.css', 'output_filename': 'css/marketing-ie.css',
}, },
'print': { 'print': {
'source_filenames': ['css/print.scss'], 'source_filenames': ['sass/print.scss'],
'output_filename': 'css/print.css', 'output_filename': 'css/print.css',
} }
} }
PIPELINE_JS = {
'application': {
'source_filenames': [
'coffee/src/calculator.coffee',
'coffee/src/courseware.coffee',
'coffee/src/feedback_form.coffee',
'coffee/src/main.coffee'
],
'output_filename': 'js/application.js'
}
}
PIPELINE_COMPILERS = [ PIPELINE_COMPILERS = [
'pipeline.compilers.sass.SASSCompiler' 'pipeline.compilers.sass.SASSCompiler',
'pipeline.compilers.coffee.CoffeeScriptCompiler',
] ]
PIPELINE_SASS_ARGUMENTS = '-r {proj_dir}/sass/bourbon/lib/bourbon.rb'.format(proj_dir=PROJECT_ROOT) PIPELINE_SASS_ARGUMENTS = '-r {proj_dir}/static/sass/bourbon/lib/bourbon.rb'.format(proj_dir=PROJECT_ROOT)
PIPELINE_CSS_COMPRESSOR = None PIPELINE_CSS_COMPRESSOR = None
STATICFILES_IGNORE_PATTERNS = ( STATICFILES_IGNORE_PATTERNS = (
"*.scss", "sass/*",
"*.rb", "coffee/*",
"*.py", "*.py",
"*.pyc", "*.pyc"
) )
################################### APPS ####################################### ################################### APPS #######################################
......
...@@ -82,3 +82,9 @@ FILE_UPLOAD_HANDLERS = ( ...@@ -82,3 +82,9 @@ FILE_UPLOAD_HANDLERS = (
'django.core.files.uploadhandler.MemoryFileUploadHandler', 'django.core.files.uploadhandler.MemoryFileUploadHandler',
'django.core.files.uploadhandler.TemporaryFileUploadHandler', 'django.core.files.uploadhandler.TemporaryFileUploadHandler',
) )
########################### PIPELINE #################################
PIPELINE_COFFEE_SCRIPT_BINARY = 'coffee'
PIPELINE_JS_COMPRESSOR = None
PIPELINE_CSS_COMPRESSOR = None
...@@ -59,11 +59,18 @@ task :test => REPORT_DIR do ...@@ -59,11 +59,18 @@ task :test => REPORT_DIR do
sh("#{django_admin} test --settings=envs.test --pythonpath=. $(ls djangoapps)") sh("#{django_admin} test --settings=envs.test --pythonpath=. $(ls djangoapps)")
end end
desc "Collect static files"
task :collectstatic, :env do |t, args|
args.with_defaults(:env => 'dev')
django_admin = ENV['DJANGO_ADMIN_PATH'] || select_executable('django-admin.py', 'django-admin')
sh("#{django_admin} collectstatic --settings=envs.#{args.env} --pythonpath=. --noinput --link")
end
desc "Start a local server with the specified environment (defaults to dev). Other useful environments are devplus (for dev testing with a real local database)" desc "Start a local server with the specified environment (defaults to dev). Other useful environments are devplus (for dev testing with a real local database)"
task :runserver, :env do |t, args| task :runserver, [:env] => [:collectstatic] do |t, args|
args.with_defaults(:env => 'dev') args.with_defaults(:env => 'dev')
django_admin = ENV['DJANGO_ADMIN_PATH'] || select_executable('django-admin.py', 'django-admin') django_admin = ENV['DJANGO_ADMIN_PATH'] || select_executable('django-admin.py', 'django-admin')
sh("#{django_admin} runserver --settings=envs.#{args.env} --pythonpath=.") sh("#{django_admin} runserver --settings=envs.#{args.env} --pythonpath=. --nostatic")
end end
task :package do task :package do
......
../sass
\ No newline at end of file
// Generated by CoffeeScript 1.3.2-pre
(function() {
window.Calculator = (function() {
function Calculator() {}
Calculator.bind = function() {
var calculator;
calculator = new Calculator;
$('.calc').click(calculator.toggle);
$('form#calculator').submit(calculator.calculate).submit(function(e) {
return e.preventDefault();
});
return $('div.help-wrapper a').hover(calculator.helpToggle).click(function(e) {
return e.preventDefault();
});
};
Calculator.prototype.toggle = function() {
$('li.calc-main').toggleClass('open');
$('#calculator_wrapper #calculator_input').focus();
return $('.calc').toggleClass('closed');
};
Calculator.prototype.helpToggle = function() {
return $('.help').toggleClass('shown');
};
Calculator.prototype.calculate = function() {
return $.getJSON('/calculate', {
equation: $('#calculator_input').val()
}, function(data) {
return $('#calculator_output').val(data.result);
});
};
return Calculator;
})();
window.Courseware = (function() {
function Courseware() {}
Courseware.bind = function() {
return this.Navigation.bind();
};
Courseware.Navigation = (function() {
function Navigation() {}
Navigation.bind = function() {
var active, navigation;
if ($('#accordion').length) {
navigation = new Navigation;
active = $('#accordion ul:has(li.active)').index('#accordion ul');
$('#accordion').bind('accordionchange', navigation.log).accordion({
active: active >= 0 ? active : 1,
header: 'h3',
autoHeight: false
});
return $('#open_close_accordion a').click(navigation.toggle);
}
};
Navigation.prototype.log = function(event, ui) {
return log_event('accordion', {
newheader: ui.newHeader.text(),
oldheader: ui.oldHeader.text()
});
};
Navigation.prototype.toggle = function() {
return $('.course-wrapper').toggleClass('closed');
};
return Navigation;
})();
return Courseware;
}).call(this);
window.FeedbackForm = (function() {
function FeedbackForm() {}
FeedbackForm.bind = function() {
return $('#feedback_button').click(function() {
var data;
data = {
subject: $('#feedback_subject').val(),
message: $('#feedback_message').val(),
url: window.location.href
};
return $.post('/send_feedback', data, function() {
return $('#feedback_div').html('Feedback submitted. Thank you');
}, 'json');
});
};
return FeedbackForm;
})();
$(function() {
$.ajaxSetup({
headers: {
'X-CSRFToken': $.cookie('csrftoken')
}
});
Calculator.bind();
Courseware.bind();
FeedbackForm.bind();
return $("a[rel*=leanModal]").leanModal();
});
}).call(this);
...@@ -24,15 +24,4 @@ If you already install all the dependencies using Bundler, you can just do: ...@@ -24,15 +24,4 @@ If you already install all the dependencies using Bundler, you can just do:
$ bundle exec guard $ bundle exec guard
This will generate the sass file for development which some debugging This will execute `django-admin collectstatic`, which will compile the sass files
information.
### Before Commit
Since this compiled style you're going to push are going to be used on live
production site, you're encouraged to compress all of the style to save some
bandwidth. You can do that by run this command:
$ bundle exec guard -g production
Guard will watch your directory and generated a compressed version of CSS.
...@@ -141,7 +141,7 @@ h1.top-header { ...@@ -141,7 +141,7 @@ h1.top-header {
} }
span.ui-icon { span.ui-icon {
background-image: url(images/ui-icons_454545_256x240.png); background-image: url(../images/ui-icons_454545_256x240.png);
} }
&.active { &.active {
......
...@@ -59,26 +59,26 @@ ...@@ -59,26 +59,26 @@
.ui-widget { font-family: Helvetica, Arial, sans-serif; font-size: 1.1em; } .ui-widget { font-family: Helvetica, Arial, sans-serif; font-size: 1.1em; }
.ui-widget .ui-widget { font-size: 1em; } .ui-widget .ui-widget { font-size: 1em; }
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Helvetica, Arial, sans-serif; font-size: 1em; } .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Helvetica, Arial, sans-serif; font-size: 1em; }
.ui-widget-content { border: 1px solid #dae5c9; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #031634; } .ui-widget-content { border: 1px solid #dae5c9; background: #ffffff url(../images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #031634; }
.ui-widget-content a { color: #031634; } .ui-widget-content a { color: #031634; }
.ui-widget-header { border: 1px solid #dae5c9; background: #7fbcfd url(images/ui-bg_highlight-soft_50_7fbcfd_1x100.png) 50% 50% repeat-x; color: #031634; font-weight: bold; } .ui-widget-header { border: 1px solid #dae5c9; background: #7fbcfd url(../images/ui-bg_highlight-soft_50_7fbcfd_1x100.png) 50% 50% repeat-x; color: #031634; font-weight: bold; }
.ui-widget-header a { color: #031634; } .ui-widget-header a { color: #031634; }
/* Interaction states /* Interaction states
----------------------------------*/ ----------------------------------*/
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #dae5c9; background: #7fbcdf url(images/ui-bg_highlight-soft_100_7fbcdf_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #7a994c; } .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #dae5c9; background: #7fbcdf url(../images/ui-bg_highlight-soft_100_7fbcdf_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #7a994c; }
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #7a994c; text-decoration: none; } .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #7a994c; text-decoration: none; }
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #7fbcdf; background: #bddeff url(images/ui-bg_highlight-soft_25_bddeff_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #7a994c; } .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #7fbcdf; background: #bddeff url(../images/ui-bg_highlight-soft_25_bddeff_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #7a994c; }
.ui-state-hover a, .ui-state-hover a:hover { color: #7a994c; text-decoration: none; } .ui-state-hover a, .ui-state-hover a:hover { color: #7a994c; text-decoration: none; }
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #dae5c9; background: #023063 url(images/ui-bg_glass_65_023063_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #dae5c9; } .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #dae5c9; background: #023063 url(../images/ui-bg_glass_65_023063_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #dae5c9; }
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #dae5c9; text-decoration: none; } .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #dae5c9; text-decoration: none; }
.ui-widget :active { outline: none; } .ui-widget :active { outline: none; }
/* Interaction Cues /* Interaction Cues
----------------------------------*/ ----------------------------------*/
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #cccccc; background: #ffffff url(images/ui-bg_flat_55_ffffff_40x100.png) 50% 50% repeat-x; color: #444444; } .ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #cccccc; background: #ffffff url(../images/ui-bg_flat_55_ffffff_40x100.png) 50% 50% repeat-x; color: #444444; }
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #444444; } .ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #444444; }
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #fa720a; background: #ffffff url(images/ui-bg_flat_55_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } .ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #fa720a; background: #ffffff url(../images/ui-bg_flat_55_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #222222; } .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #222222; }
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #222222; } .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #222222; }
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } .ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
...@@ -89,14 +89,14 @@ ...@@ -89,14 +89,14 @@
----------------------------------*/ ----------------------------------*/
/* states and images */ /* states and images */
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_adcc80_256x240.png); } .ui-icon { width: 16px; height: 16px; background-image: url(../images/ui-icons_adcc80_256x240.png); }
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_adcc80_256x240.png); } .ui-widget-content .ui-icon {background-image: url(../images/ui-icons_adcc80_256x240.png); }
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_031634_256x240.png); } .ui-widget-header .ui-icon {background-image: url(../images/ui-icons_031634_256x240.png); }
.ui-state-default .ui-icon { background-image: url(images/ui-icons_adcc80_256x240.png); } .ui-state-default .ui-icon { background-image: url(../images/ui-icons_adcc80_256x240.png); }
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_adcc80_256x240.png); } .ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(../images/ui-icons_adcc80_256x240.png); }
.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } .ui-state-active .ui-icon {background-image: url(../images/ui-icons_454545_256x240.png); }
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_adcc80_256x240.png); } .ui-state-highlight .ui-icon {background-image: url(../images/ui-icons_adcc80_256x240.png); }
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_fa720a_256x240.png); } .ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(../images/ui-icons_fa720a_256x240.png); }
/* positioning */ /* positioning */
.ui-icon-carat-1-n { background-position: 0 0; } .ui-icon-carat-1-n { background-position: 0 0; }
...@@ -286,8 +286,8 @@ ...@@ -286,8 +286,8 @@
.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 2px; -webkit-border-bottom-right-radius: 2px; -khtml-border-bottom-right-radius: 2px; border-bottom-right-radius: 2px; } .ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 2px; -webkit-border-bottom-right-radius: 2px; -khtml-border-bottom-right-radius: 2px; border-bottom-right-radius: 2px; }
/* Overlays */ /* Overlays */
.ui-widget-overlay { background: #eeeeee url(images/ui-bg_flat_0_eeeeee_40x100.png) 50% 50% repeat-x; opacity: .80;filter:Alpha(Opacity=80); } .ui-widget-overlay { background: #eeeeee url(../images/ui-bg_flat_0_eeeeee_40x100.png) 50% 50% repeat-x; opacity: .80;filter:Alpha(Opacity=80); }
.ui-widget-shadow { margin: -4px 0 0 -4px; padding: 4px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .60;filter:Alpha(Opacity=60); -moz-border-radius: 0px; -khtml-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; }/* .ui-widget-shadow { margin: -4px 0 0 -4px; padding: 4px; background: #aaaaaa url(../images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .60;filter:Alpha(Opacity=60); -moz-border-radius: 0px; -khtml-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; }/*
* jQuery UI Resizable 1.8.16 * jQuery UI Resizable 1.8.16
* *
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
......
from django.conf import settings from django.conf import settings
from django.conf.urls.defaults import patterns, include, url from django.conf.urls.defaults import patterns, include, url
from django.contrib import admin from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.conf.urls.static import static
import django.contrib.auth.views import django.contrib.auth.views
...@@ -90,4 +90,4 @@ if settings.DEBUG: ...@@ -90,4 +90,4 @@ if settings.DEBUG:
urlpatterns = patterns(*urlpatterns) urlpatterns = patterns(*urlpatterns)
if settings.DEBUG: if settings.DEBUG:
urlpatterns += staticfiles_urlpatterns() urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment