I wish to use date-fns in my django project but not entirely sure how to proceed - I cannot rely on a CDN and need to somehow get it installed. I have run npm init in my root folder followed by npm install date-fns. This generated a node_modules folder and a package.json file.
Not entirely sure how to proceed after this. What are the necessary steps?
Do I just use
<script src="{% static 'node_modules/date-fns' %}"></script>
in my base.html file?
The search path used when the static template operator is used is defined in the settings.py file in STATICFILES_DIR (docs). This will allow the static operator to find the library files and generate the URL.
Note, however, that the files still need to be served by the web server from the expected path defined by STATIC_URL. The manage.py tool in the project root includes a command collectstatic that can copy all of the static search directories into one location to make serving those files simpler.
Also note that you showed a code sample that references the npm library directory from the script tag as a script, but that the browser will not know how to find the script from the directory. node usually uses the library's package.json to find the entry point. It will be necessary to specifically call out the script files of interest inside the package.
One option is to use a bundling tool like webpack or rollup to collect all of the resources into a single location.
Another option is to add the node_modules paths to the static path, perhaps with prefixes. It might look something like the following.
STATIC_URL = '/static/'
STATIC_ROOT = 'dist/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
# This defines a prefix so the url paths will become `/static/node_modules/...`
('node_modules', os.path.join(BASE_DIR, 'node_modules/')),
)
Specifically include index.js rather than just date-fns from the template file.
{% load static %}
<!-- .... -->
<script src="{% static 'node_modules/date-fns/index.js' %}"></script>
If collecting and serving static files from STATIC_ROOT the following command would collect the STATICFILES_DIRS contents, in this example, into dist/static.
python manage.py collectstatic
Related
I'm using PyCharm to manage my django files and for the front end I'm using Bootstrap. I'm currently using the CDN method to point to the bootstrap files in my base.html file.
I've recently come to a point where I want to customize some of the SCSS variables that bootstrap provides, but I'm puzzled and can't find a guide anywhere to how to do this with my configuration.
I used npm to install the bootstrap files to my outer project folder. I've tried installing django-sass-compiler using pip, and then adding the required setting to my settings.py, but when I ran the command "python manage.py sass-compiler" (as per the PyPi docs), I got "ModuleNotFoundError: No module named 'django_sass_compiler'"
I'm assuming that if I were to get that working then it would compile my custom SCSS file into a CSS file that would overwrite my current 'main.css' (is that right?), however I can't even figure out that part.
If someone could please point me in the right direction then that would be great, there really isn't a lot of help out there for sass, pycharm, django & bootstrap together.
Yes, you will have to compile the CSS manually. You can use tools like Koala.
To accomplish that in Django, You will have to:
Create a directory named static at your project level directory. In satic add another folder called css. Go ahead and add the compiled CSS file.
Change
STATIC_URL = 'static/'
to
STATIC_URL = '/static/'
and add
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
In your base.html file at the very top add
{% load static %}
and you can link the base.html file to your compiled CSS file like shown below:
<link rel="stylesheet" href="/static/css/mycss.css">
I have a static directory inside my apps folder. I added this line of code to my projects settings.py file
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
'/var/www/static/',
]
The file continues to result in a 404 not found. I'm getting stuck, what should I do?
It probably isn't mistake in your static files settings. But to be sure the relevant settings for static folder in app directories is STATICFILES_FINDERS https://docs.djangoproject.com/en/2.1/ref/settings/#staticfiles-finders. But the AppDirectoriesFinder should be present by default so it is probably OK.
Your problem is probably in your URL scheme:
For development purposes make sure you have django.contrib.staticfiles in your installed apps, DEBUG = True and STATIC_URL = '/static/' (or something similar). Then you should be able access the files.
For deploying it is more complicated but essentially you have setup STATIC_ROOT, before starting the server run python manage.py collectstatic command which will copy all static files to one location and then setup your server (Nginx) to serve the files from this folder under /static/ URL. Here is the official documentation https://docs.djangoproject.com/en/2.1/howto/static-files/#deployment
Note: if your app is foo and you have bar file in your static directory under foo app the URL for the file will be /static/foo/bar.
I have recently added npm to my project in order to keep better track of my js dependencies. Previously I have just been git cloning to my static/vendor folder.
I've also added gulp , but have only got it doing hello world things right now. It seems simple enough - it can watch files, minify assets, compile Sass. Eventually I will probably switch to Webpack, but gulp is simple and working for now. I don't want to use django-compressor or django-pipeline.
So let's say I run npm install vis to pull in visjs. It gets added to node_modules and a record is added to package.json dependencies.
A) Do I reference vis/dist right where it is in node_mods in my template scripts?
<script src="/node_modules/vis/dist/min-vis.js' %}"></script>
# right now it's <script src="{% static 'vendor/min-vis.js' %}"></script
B) Should gulp be listening for changes to package.json dependencies and replicating vis/dist to static/vendor or static/js when it sees changes there?
I keep seeing people talking about handling STATICFILE_DIRS when they talk about npm and gulp. Right now mine is just set to the following. Will this change?
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
STATICFILES_DIRS tells Django where to find all the static assets (which will later be "collected" for a deployment, but we can ignore that for the moment). That setting will need to include wherever you have gulp placing the processed assets, or you can have gulp put them into $BASE_DIR/static to avoid changing your setting if you prefer.
From there, you should be using the static templatetag
{% load static %}
<script src="{% static 'your_bundled_asset.min.js' %}"></script>
Note that if your asset is in a nested directory under the STATICFILES_DIRS entry it is under, you may need to prefix that. {% static 'js/asset.min.js' %}.
So Django can use the dev location ($BASE_DIR/static) or the "collected" location when deployed (./manage.py collectstatic --noinput pulls all static files to one location for simplified serving).
I dont know if I am confusing the purpose of collectstatic. Here's my settings module:
# BASE_DIR is the location of my django project folder
STATIC_URL = '/this.static/'
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "ve_static_root")
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "this.static"),
os.path.join(BASE_DIR, "this.media"),
)
MEDIA_URL = '/this.media/'
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "ve_media_root")
Here, I placed both my static files and media files in STATICFILES_DIRS so that I can use media files as an easy reference when I recall/embed images into my markdown documents, but as you can also see, I made a path for MEDIA_ROOT, which needs to be different from STATIC_ROOT. My concern is that I placed my media folder, this.media, in the STATICFILES_DIRS folder, which allows me to call the images or videos into the Django templates using these staticfile filters, like {% static 'image/file/path/here' %}. As convenient as that is, I also wondered whats the point of the MEDIA_ROOT if all my files, images/videos and web design files, are just going into STATIC_ROOT? As far as I know, Django doesn't have a collectmedia command, so I don't really have anything collecting into the MEDIA_ROOT folder. I just have it out here, empty and all.
Am I missing something about this? Anyone understand Django's perspective on this? Whats your perspective? I am not sure if collectstatic should involve collecting media files as well, especially when I have a MEDIA_ROOT. I looked at the docs on static files and they really arent very helpful with regards to media files.
The Django documentation discourages having the static root and media root as the same directory (having them within the same parent directory is presumably alright). While not fleshed out in the docs specifically, the reason revolves around the inherent uncertainty when it comes to user-generated files. If both static and media files are served from similar directories, then a user, under the right circumstances, might be able to upload any file, which might subsequently be served. This of course creates major security vulnerabilities – this is the motivation for having two separate directories for these two classes of files.
collectstatic relies on the STATICFILES_DIRS array to generate a list of directories through which collectstatic should search for static files. If you are including media files in STATICFILES_DIRS, then, upon running collectstatic (as instigated either by you or by an automated service like Fabric), media and static files will live in the same output directory.
The documentation also has a section about Serving files uploaded by a user during development, which you can do simply by accessing the url at which the media files exist, as you would with any static file. You can simply append
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
to your URL configuration.
django.contrib.staticfiles.views.serve() however, should not be used for deployment. I've written more about this here. It is highly recommended that you serve your static files (and store and serve media files, as necessary) from a directory outside of your project's, in production.
Media files are files that users upload to your Django site.
Static files are files that you want to serve as part of the site (usually CSS, JavaScript and images).
As such I wouldn't expect collectstatic to do anything with media files.
This seems to be a source of much confusion judging by the amount of similar titles on the subject, however trying everything I could find on static files with the django development server I've almost given up hope!
So my static files are served from C:/Users/Dan/seminarWebsite/static/, in which I have sub folders for images, css etc.
SETTINGS:
STATIC_ROOT = 'C:/Users/Dan/seminarWebsite/static/'
STATIC_URL = '/static/'
The static files app is also active.
URLS:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
TEMPLATE:
"{{ STATIC_URL }}images/vision.jpeg"
However only a broken link appears and at this address: http://127.0.0.1:8000/homepage/images/vision.jpeg and I don't think it should be at that address (homepage is the url name of the page the static image file is being called to).
Based on what you've posted so far, it looks like you're following the docs for django.contrib.staticfiles. I agree that the docs can be difficult to follow especially if one is new to django.
I believe the confusion stems from the fact that django.contrib.staticfiles has two modes of operation:
During the development phase where the development server is used, it dynamically searches for static files in predefined directories and make it available on STATIC_URL
For deployment, it assists in collating static files to a single directory (defined using STATIC_ROOT) so that the static files can be hosted using a webserver suited for static files. This collation is done using python ./manage.py collectstatic.
Here's a quick summary of how to get up and running. I haven't had a chance to try it out so there may be mistakes. Hopefully this will help you get started and at the very least help you understand the docs. When in doubt, do refer to the docs.
Hosting static files on the development server
Make sure you have 'django.contrib.staticfiles' in INSTALLED_APPS
Specify STATIC_URL. This will be the path where your static files will be hosted on.
STATIC_URL = '/static/'
Make sure your files are in the correct directories. By default, staticfiles will look for files within the static/ directory of each installed app, as well as in directories defined in STATICFILES_DIRS. (This behaviour depends on backends listed in STATICFILES_FINDERS).
In your case, you'd probably want to specify your directory in STATICFILES_DIRS:
STATICFILES_DIRS = (
'C:/Users/Dan/seminarWebsite/static/',
)
Make the view accessible by adding the following to the end of urls.py:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
Make sure you have DEBUG = True in settings.py.
That's it.
If you run your dev server (./manage.py runserver), you should be able to access your file via http://localhost:8000/static/images/vision.jpeg (which serves C:/Users/Dan/seminarWebsite/static/images/vision/jpeg).
Linking to static files in your templates
There are two ways to get a correct link for your static files - using the staticfiles template tag, and making STATIC_URL accessible to your templates. Since you've attempted the latter, we'll stick to that.
Make sure you have 'django.core.context_processors.static' in TEMPLATE_CONTEXT_PROCESSORS. If you haven't redefined TEMPLATE_CONTEXT_PROCESSORS then there is nothing to do since it should be there by default.
Make sure you use RequestContext when rendering your template. Example:
from django.template import RequestContext
# ...
def some_view(request):
# ...
return render_to_response('my_template.html', {
"foo" : "bar", # other context
}, context_instance = RequestContext(request))
You should now be able to use the following in your my_template.html:
<a href="{{ STATIC_URL }}images/vision.jpeg" />
Hosting static files on production server.
If all the static files you need to serve are store in that one directory (C:/Users/Dan/seminarWebsite/static), then you're almost there. Simple configure your webserver to host that directory on /static/ (or whatever you set STATIC_URL to) and you're good to go.
If you have files scattered in different directories and/or app specific static files, then you'll need to collate them.
Set STATIC_ROOT to the directory where you want to store the collated files.
Run ./manage.py collectstatic to do the collation.
Configure your webserver to host the that directory (STATIC_ROOT) on /static/ (or whatever you set STATIC_URL to).