Django 3.1: Choice of static files directory - django

I have seen different ways in tutorials where the static files directory keep on changing.
1. Some put static files in the project root directory. Example
myproject
|__blog
| |__migrations
| |__static
| |__templates
mysite
|
static
|__blog
|__css
|__js
2. Some put the static files in the root directory of the app it is serving. Example
myproject
├── blog
│ ├── migrations
│ ├── static
│ └── templates
└── mysite
Where should static files be located?

It's whatever you want.
Personally, I prefer to keep my static resources at one place instead of scattered in different applications. Moreover, most staticfiles are needed in multiple apps, so I just put everything one place and serve from there.

Related

Project architectures differences for Django + Vuejs (or other) integration

I'm currently looking at project setups for a Django + Vuejs project (though I guess the question is likely just as valid for other frontends, react, svelte etc.).
It seems that there are mainly 2 approaches that come up often, resulting in the following project structure:
The frontend embedded within the Django project (perhaps as a git submodule):
root
├── djangoapp
├── djangoproject
├── manage.py
├── requirements.txt
├── static
├── venv
└── vueproject
├── node_modules
├── package.json
├── public
└── src
Another approach is to have them at the same level from project root, as 2 seperate projects actually (or I guess both could be git submodules to a "wrapper" project), so essentially:
root
├── djangoproject
│   └── <django files & folders>
└── vueproject
└── <vue files & folders>
With the 2nd approach, it seems you basically just see Django as an API. Stuff like collectstatic does not (?) come into play. In development, you need a server up to serve Django's api, and a dev server for the vue frontend.
With the 1st approach (if I understand correctly), seems that you build the Vue static files, and then manage all of that with Django's collectstatic/static files management.
Seems the 2nd approach is a better decoupling of the 2 components. With the 1st, you need to configure vue (or vite) rather specifically and Django's static files as well. What we gain by doing this isn't obvious to me - the more I think about it, the more it seems clear that the 2nd approach is better.
What potential advantages would there be in the 1st approach? Dev conveniences I'm not seeing? Easier deployment? Or is it just a somewhat outdate approach that still lingers the web?

How do I run unit tests from smaller applications inside of a parent directory?

I'm working in a repository with multiple smaller applications for various lambdas. I'd like to be able to run cargo test from the top level directory, but I can't seem to find a way to get this to work since the files aren't nested within a top level src directory.
├── cloudformation
├── apps
│ ├── app1
│ │ └── src
│ └── app2
│ └── src
└── otherStuff
Ideally I could run cargo test from the top level and it would dig into apps and run tests from the src directory nested within each individual app. Is there a way to accomplish this?

how to use Hugo with github pages to automatically update content

I am using Hugo to deploy a static page to github pages
I have a git repo in the /public folder but the contents of the /static folder are not a part of the repository. Therfore they are not uploaded to the username.github.io page.
the /static folder contains images and css files. This is why my page does not look good after pushing to github.
My workaround is that each time I manually copy the /static folder into the /public folder after I build the site.
I think there should be a better solution and I am probably missing something in the config.toml file of the hugo workflow.
I am following the instructions from this site
Any ideas how to automatically include /static files into the repository?
Hugo copies all the files in the static/ directory into the public/ directory when your site is rendered. For example, if you have a static/ folder that looks like this:
.
├── css
│   └── main.css
└── img
├── favicon.png
└── avatar.png
Then when you build your site, the public/ folder will look like this:
.
├── css
│ ├── main.css
│ └── <theme css files>
├── img
│ ├── favicon.png
│ ├── avatar.png
│ └── <theme images>
<more content folders>
So the files in your static folder are probably being included already. The problem is likely to be that your theme is looking for your static files in the wrong place. Take a look at your theme documentation and see if it says anything about static assets.

What good way for structure of project and owners of dirs in django?

Imagine that my django project contain few apps. On server it located at /var/www/ProjectName dir. My username is Foo and sometimes i want edit file of server. Which best solution for next questions?
What owner of /var/www?
What owner of /var/www/ProjectName?
What apache process owner?
Where locate static files (css, js)? Is it from all apps in one dir or different dirs for different apps? What Owner of this dir?
Where locate media files (with upload users)? Is it from all apps in one dir or different dirs for different apps? What Owner of this dir?
What owner of py and pyc files, dirs of apps?
PS. Maybe project is located at my home directory?
I have some suggestions about that, but I would like to hear more experienced people.
on ubuntu 12.04 root
drwxr-xr-x 3 root root 4096 Nov 8 11:59 www
cd /var/www && ls -la to see owner, probably root?
www-data, on 12.04 www-data homes directory is /var/www (www-data:x:33:33:www-data:/var/www)
you can collectstatic to whatever directory you want in your project. I often have a directory called static next to manage.py. The owner is probably the same as the owner of your django project. You only need to allow read access to this folder for apache
You will probably want to consider a centralized media folder, instead of having media for each app. For both static and media you can fairly easily upload everything to s3 using django-storages
the owner can be anyone you want, I can't say the owner because it is your machine. But, I think, the webserver will need to execute the py files, so you can change your permissions to allow for this.
You can locate the project whereever you want. In apache virtual host you give the location of your wsgi file. There is no reason your project must live in /var/www
Here is the structure I'm using.
django/
├── project_virtualenv (virtualenv folder)
└── versioned (folder for things that are versioned)
├── devdoc (documentation)
└── py (code)
└── project (django project)
├── django_app (django app)
│  
├── project (project folder)
   ├── files
   │   ├── media (media, user uploads, etc)
   │   ├── production_static (statics for production)
   │   └── static (statics for development)
   └── templates
  
The directory django is located in the home directory on the production server, only the wsgi.py is in the publicly available folder (in my case /home/user/public_html/wsgi.
I've chmoded everything in the Django folder to 777 just to get everything working on the testing production server. Not sure what are the security risks, even dough the files aren't directly served.

Separation of Static Files & Assets with Django Compressor & Usage of collectstatic

I'm having a really hard time getting my head around the use of django-compressor.
Here's what I'm attempting to accomplish:
Separation of Static Files & Assets (LESS, Coffeescript)
I would like to separate my LESS CSS and Coffeescript files into an assets directory
e.g.
app
└── assets
├── coffee
│ └── script.coffee
└── less
└── style.less
Leaving static assets such as images in my static directory
e.g.
app
└── static
├── hello.txt
└── photo.jpg
To do this, I've added the assets path to my STATICFILES_DIRS variable to allow django-compressor to find the files (which works as expected). Is this the correct approach? I have been trying to find an independent load path dedicated to django-compressor but didn't have any luck as I don't intend for these assets to be served as statics.
Collection of Files for Production Deployment
For deploying to production, I would then like the compiled CSS & JS files along with other media in my app/static directory (e.g. images and so on) to be collected to an app/static-prod directory. But this doesn't work out so well because the assets are also collected when using the collectstatic command.
e.g.
(django-cpython)fots#fotsies-ubprecise-01:~/django_learning$ ./manage.py collectstatic --noinput
Copying '/home/fots/django_learning/app/assets/less/style.less'
Copying '/home/fots/django_learning/app/assets/less/import.less'
Copying '/home/fots/django_learning/app/assets/coffee/script.coffee'
Copying '/home/fots/django_learning/app/static/photo.jpg'
Copying '/home/fots/django_learning/app/static/hello.txt'
5 static files copied.
Using the ./manage.py compress command only takes tare of my compiled files, not photo.jpg or hello.txt in this example.
The only possible way I've found to do this is using the --ignore flag with collectstatic
e.g.
(django-cpython)fots#fotsies-ubprecise-01:~/django_learning$ ./manage.py collectstatic --noinput --ignore=less --ignore=coffee
Copying '/home/fots/django_learning/app/static/photo.jpg'
Copying '/home/fots/django_learning/app/static/hello.txt'
2 static files copied.
I've also messed around with the COMPRESS_ROOT and COMPRESS_URL configuration variables but these only cause further trouble. Changing COMPRESS_ROOT resolves the collectstatic issue but now when using the compress command, the generated files end up in a different location to the static files.
These solutions hardly seem elegant. Is there a better way to do this? I feel like I'm missing something.
Thanks in advance for any help :)
I thought I'd provide the best solution I have found so far but please feel free to suggest better alternatives.
The biggest issue preventing my requirement is the fact that django-compressor uses the same path for its finder and output. The best solution I've found is as follows.
Creating a custom finder
We first create a custom finder based on a new setting I call COMPRESS_SOURCE_ROOT
from compressor.storage import CompressorFileStorage
from compressor.finders import CompressorFinder
from compressor.conf import settings
class CompressorFileAltStorage(CompressorFileStorage):
"""
This alternative django-compressor storage class is utilised
specifically for CompressorAltFinder which allows an independent
find path.
The default for ``location`` is ``COMPRESS_SOURCE_ROOT``.
"""
def __init__(self, location=None, base_url=None, *args, **kwargs):
if location is None:
location = settings.COMPRESS_SOURCE_ROOT
# The base_url is not used by the Finder class so it's irrelevant
base_url = None
super(CompressorFileAltStorage, self).__init__(location, base_url,
*args, **kwargs)
class CompressorAltFinder(CompressorFinder):
"""
A staticfiles finder that looks in COMPRESS_SOURCE_ROOT
for compressed files, to be used during development
with staticfiles development file server or during
deployment.
"""
storage = CompressorFileAltStorage
Using this new finder
Simply add this finder to your STATICFILES_FINDERS setting in addition to the usual 'compressor.finders.CompressorFinder'
e.g.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
'mycomp.CompressorAltFinder',
'compressor.finders.CompressorFinder',
)
And now set up a new setting called COMPRESS_SOURCE_ROOT
e.g.
COMPRESS_SOURCE_ROOT = os.path.join(APP_DIR, 'assets')
I've also set my STATIC_ROOT too
STATIC_ROOT = os.path.join(APP_DIR, 'static-prod')
Testing the Solution in Development
I specifically tested my LESS source code compilation
(django-cpython)fots#fotsies-ubprecise-01:~/django_learning$ tree app/assets
app/assets
├── coffee
│ └── script.coffee
└── less
├── import.less
└── style.less
With template tags
{% compress css %}
<link rel="stylesheet" type="text/less"
href="{{ STATIC_URL }}less/style.less" />
{% endcompress %}
This is read from the assets directory successfully and updated when I change the files.
The output is placed in the static-prod directory:
(django-cpython)fots#fotsies-ubprecise-01:~/django_learning$ tree app/static-prod/
app/static-prod/
└── CACHE
├── css
│ ├── style.5abda32cfef7.css
│ └── style.6ca1a3d99280.css
└── js
└── script.8cb4f955df19.js
3 directories, 3 files
Testing the Solution for Production
For your reference, here's what my static directory looks like
(django-cpython)fots#fotsies-ubprecise-01:~/django_learning$ tree app/static
app/static
├── hello.txt
└── photo.jpg
0 directories, 2 files
So here we go
(django-cpython)fots#fotsies-ubprecise-01:~/django_learning$ rm -rf app/static-prod
(django-cpython)fots#fotsies-ubprecise-01:~/django_learning$ ./manage.py collectstatic --noinput
Copying '/home/fots/django_learning/app/static/photo.jpg'
Copying '/home/fots/django_learning/app/static/hello.txt'
2 static files copied.
(django-cpython)fots#fotsies-ubprecise-01:~/django_learning$ ./manage.py compress
Found 'compress' tags in:
/home/fots/django_learning/app/templates/layout.html
Compressing... done
Compressed 2 block(s) from 1 template(s).
(django-cpython)fots#fotsies-ubprecise-01:~/django_learning$ tree app/static-prod
app/static-prod
├── CACHE
│ ├── css
│ │ └── 5abda32cfef7.css
│ ├── js
│ │ └── 3b9d1c08d2c5.js
│ └── manifest.json
├── hello.txt
└── photo.jpg
3 directories, 5 files
I then ran the webserver as follows and confirmed that the site was operational
./manage.py runserver 0.0.0.0:8000 --insecure
Hope this helps somebody out there :)