why Django put application at the same level of my project folder? - django

since Django 1.4 (I think) django create a folder for my project when I start a project. Django add a folder for any application I created (with python manage.py startapp) at the same level of my project folder.
Project_name
|---project_name_dir/
|---application_dir/
`---manage.py
I really like the following folder structure:
Project_name
|---project_name_dir/
| |---application_dir/
| | |-- __init__.py
| | |-- models.py
| | |-- tests.py
| | `-- views.py
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| |-- wsgi.py
| |---templates/
| | `---application_dir/
| `---static/
| |---css/
| |---font/
| |---img/
| `---js/
|---deployment/
|---documentation/
|---config/
`---manage.py
Because I have a folder with all my django files (project_name_dir/) and other directories for non django files.
So why Django put application at the same level of my project folder?

In Django, the position of the application directory is not considered. Django only uses the name of the application.
Thus, the position of the application is basically a matter of convenience of the programmer.
This is also the reason why two apps should not have the same name: even if they are imported in INSTALLED_APPS as
('app.app1', 'app1')
Django only concerns with the last part after the dot, i.e. app1.
So, in the end, you can use the directory structure you want, as long as the apps' names don't collide and you point to the app on INSTALLED_APPS. Because of this, if there isn't any special reason, you should put them on the project's root, like Django does.

Related

Can I put custom settings in Django's settings.py

I have several custom settings I'd like to define in my Django app. Up to this point, I've put them in a constants.py file in each individual app.
myapp/constants.py
HOURS_PER_EVENT = 4
MAX_MEMBERS_PER_EVENTS = 150
MAX_EVENTS_PER_YEAR = 10
...
It just occurred to me I may be able to put these in settings.py and after a quick test everything seems to work fine. Is this allowed or is settings.py reserved for core django settings defined here? If it's not allowed, is there a better place to put these.
Yes it is allowed to extend your application settings, and it is really simple to do it. All that you need to do is a simple manipulation from your current project settings.py to a module settings.
Your file structure is probably like the following:
mysite/
|-- mysite/
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| +-- wsgi.py
+-- manage.py
What you need to do is to change it to something like this:
mysite/
|-- mysite/
| |-- __init__.py
| |-- settings/
| | |-- __init__.py
| | |-- base.py <-- (this is your old settings.py)
| | +-- constants.py
| |-- urls.py
| +-- wsgi.py
+-- manage.py
This is a pattern described in this tutorial.

How to import multiple class objects from seperate folders?

I built a python 2.7 application with the below directory structure for my relevant files. How do cal methods located in different folder locations?
Data-Wrangling-OpenStreetMap-data
|
+---- process_data
| |
| +---- __init__.py
| |
| +---- data_cleaner.py
|
+---- main_code.py
|
+---- audit _data
| |
| +---- __init__.py
| |
| +---- audit_file.py
I have succeeded in doing it correctly for one class referenced from main_code.py via the use of:
from process_data.data_cleaner import DataCleaner
However, if attempt a similar pattern for another class located in seperate folder referenced by main_code.py for via the use of the import statement
from audit_data.audit_file import AuditFile
I get the error:
ImportError: No module named audit_data.audit_file
Any ideas as to what I may be overlooking and/or guidance on what further details I need to post to help find the solution to my problem?
from process_data.data_cleaner import data_cleaner
as data_cleaner is the file name data_cleaner.py and the second one data_cleaner is a class defined in it.
The cause of my problem was a silly one;
The folder containing the class I was calling was named audit _file whilst the folder I was calling within my code was audit_file
What didnt work
from audit_data.audit_file import AuditFile
What worked
from audit _data.audit_file import AuditFile
For those reading this watch out for unintended spaces in your folder names

How solve"no python application found check your startup logs" error for Django + uWSGI + nginx stack

I user Django 1.10 with uWSGI and nginx on ubuntu 16.04 and deploy my app with ansible. My project have not default structure, but quite common ( thank Two scoopce for this :).
I use split dev and production settings and config folder instead 'name' project folder. It's looks like this:
|-- config
| |-- __init__.py
| |-- settings
| | |-- __init__.py
| | |-- base.py
| | `-- dev.py
| |-- urls.py
| |-- wsgi_dev.py
| `-- wsgi_production.py
|-- manage.py
`-- requirements.txt
My production.py genarate from ansible with security encrypt and locate in config/settings.
With this config i get "no python application found check your startup logs". Uwsgi don't see my application.
( {{ }} it's jinja2 syntax for ansible )
/etc/uwsgi/sites/{{ project_name }}
[uwsgi]
chdir = {{ django_root }}
home = /home/{{ project_user }}/venvs/{{ project_name }}
module = config.wsgi_production:application
master = true
processes = 5
socket = /run/uwsgi/{{ project_name }}.sock
chown-socket = {{ project_user }}:www-data
chmod-socket = 660
vacuum = true
After several weeks i can find problem in my wsgi.py. It common solution use os.environ['ENV'] for DJANGO_SETTINGS_MODULE, but with deffrent users and permissions its dosen't work.
If you use in your wsgi.py file something like this:
os.environ["DJANGO_SETTINGS_MODULE"] = "config.settings." + os.environ["ENV"]
And have problem with no python application found - split your wsgi file. I can catch that os.environ["ENV"] return empty string. I add it for my all user, use source and etc. But uwsgi in emperior mode don't see it.
You sould use wsgi_dev.py and wsgi_production.py where you can write somethink like this os.environ["DJANGO_SETTINGS_MODULE"] = "config.settings.production". It's not so elegant but solve this problems fine.
For use splitting wsgi you can write something like this in wsgi.py
import os
from django.core.wsgi import get_wsgi_application
if os.environ.get('DEV') is True:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.dev")
else:
os.environ.setdefault("DJANGO_SETTINGS_MODULE",
"config.settings.production")
application = get_wsgi_application()

Nginx + uwsgi + Django: Error in url rewriting

I'm trying to deploy a Django project on under a sub path of my institute website.
Let's say server IP is: X1.X2.X3.X4.
And xyz.edu/tnp probably points to X1.X2.X3.X4/portal/.
Structure of Django project is like this:
.
|-- project
| |-- app1
| |-- app2
| |-- project_nginx.conf
| |-- project_uwsgi.ini
| |-- db.sqlite3
| |-- manage.py
| |-- media
| |-- README.md
| |-- static
| `-- uwsgi_params
|-- README.md
|-- requirements
| |-- base.txt
| |-- dev.txt
| |-- prod.txt
| `-- test.txt
|-- requirements.txt
|-- static_cdn
| |-- admin
| .....
And my URL scheme in project/urls.py looks like this:
url(r'^app1/', include('app1.urls')),
url(r'^app2/', include('app2.urls')),
url(r'^admin/', include(admin.site.urls)),
On my local server, following scheme is working perfectly.
* 127.0.0.1:8000/app1/
* 127.0.0.1:8000/app1/login/
* 127.0.0.1:8000/app1/homepage/
* 127.0.0.1:8000/app2/somepage
* 127.0.0.1:8000/admin/
I want to map my URLs on my deployment server, so that
xyz.edu/tnp/app1 links to X1.X2.X3.X4/portal/app1 and
xyz.edu/tnp/app2 links to X1.X2.X3.X4/portal/app2
xyz.edu/tnp/admin links to X1.X2.X3.X4/portal/admin
and so on.
The problem is the suffix portal in X1.X2.X3.X4/portal/. When I type xyz.edu/tnp/app1 in browser, the error I'm receiving is
Using the URLconf defined in portal.urls, Django tried these URL patterns, in this order:
^app1/
^app2/
^media/(?P.)$
^static/(?P.)$
The current URL, portal/app1/, didn't match any of these.
Now I think of two approaches:
Manually prepend portal to all urls in project/urls.py
Drop the prefix portal in the portal_nginx.conf file.
First approach isn't working for internal urls. The index page for all apps, i.e. app1, app2 and so on, is working fine but for other urls, they are being rendered as xyz.edu/portal/login instead of xyz.edu/tnp/app1/login.
Second approach, as mentioned here and here, seems promising, but its not working for me. Maybe I'm doing something wrong. Following are my project_nginx.conf and project_uwsgi.ini files.
project_uwsgi.ini
[uwsgi]
chdir = ...
# Django's wsgi file
module = project.wsgi
# the virtualenv (full path)
home = ...
# master
master = true
# maximum number of worker processes
processes = 10
# the socket (use the full path to be safe
socket = ...
# clear environment on exit
vacuum = true
project_nginx.conf
upstream django {
server unix://.../.../project.sock; # for a file socket
# server 127.0.0.1:8001;
}
# configuration of the server
server {
listen 80;
server_name xyz.edu; # substitute your machine's IP address or FQDN
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /usr/share/nginx/.../project/media;
}
location /static {
alias /usr/share/nginx/.../project/static;
}
# Finally, send all non-media requests to the Django server.
location /portal/ {
rewrite /portal/(.*) /$1 break;
uwsgi_pass django;
# # the uwsgi_params file you installed
include /usr/.../wsgi_param
# uwsgi_param SCRIPT_NAME /portal/;
# uwsgi_modifier1 30;
}
}

Where to store static/template files in Django according to "Two Scoops of Django"

I'm a reader and a big fan of the popular book Two Scoops of Django.
The book is full of great ideas, but there is one which is not that clear to me.
The authors advice to create a static and a templates folder in the Django project root.
That template folder is meant for "site-wide templates" (stated at pag.24).
Plus at pag.162 they say that "templates should usually go into the root folder of the Django project... The only exception is when you bundle up an app into a third-party package".
They don't mention it explicitly in ch.12 but I guess it is good to create a folder for each app (with the same name as the app) in the templates root.
Let's suppose that in my icecreamratings Django project I have 2 apps:
flavors with 2 templates: new_flavor.html and details.html
profiles with 1 template: details.html
All templates inherit from base.html.
I guess they would suggest the following structure:
icecreamratings_project/
|-- ...
|-- icecreamratings/ # Django project root
|-- ...
|-- static/
|-- templates/
|-- 404.html
|-- 500.html
|-- base.html
|-- flavors/ # same name as app flavor
| |-- new_flavor.html
| |-- details.html
|-- profiles/ # same name as app profiles
|-- details.html
Did I get it correctly?
On the other hand, the Django official docs suggests to create a static folder in each app and, inside it, a subfolder with the same name as the app, like: my_app/static/my_app/myimage.jpg.
So we have 2 different strategies: a unique template folder and many static folders (one in each app).
Having two different strategies is clearly a bad choice.
So, what do you think of storing in each app a template and static folder?
Something like this:
icecreamratings_project/
|-- ...
|-- icecreamratings/ # Django project root
|-- ...
|-- static/ # site-wide static files
| |-- bootstrap/ # bootstrap source files
| |-- jquery/ # jquery source files
| |-- css/ # css files used by base.html (and others in templates root)
| |-- js/ # javascript files used base.html (and others in templates root)
| |-- img/ # img files files used base.html (and others in templates root)
|-- templates/ # site-wide templates
| |-- 404.html
| |-- 500.html
| |-- base.html
|-- flavors/ # an app
|-- static/
| |-- flavors/ # static files specific for this app
| |-- css/ # css files for flavor app templates
| |-- js/ # javascript files for flavor app templates
| |-- img/ # img files for flavor app templates
|-- templates/ # template files specific for this app
|-- new_flavor.html
|-- details.html
The django official doc does not suggest your to create a static folder in each app. Instead it prefer to store the static dir under the project dir.
Static file namespacing
Now we might be able to get away with putting our static files
directly in my_app/static/ (rather than creating another my_app
subdirectory), but it would actually be a bad idea. Django will use
the first static file it finds whose name matches, and if you had a
static file with the same name in a different application, Django
would be unable to distinguish between them. We need to be able to
point Django at the right one, and the easiest way to ensure this is
by namespacing them. That is, by putting those static files inside
another directory named for the application itself.
The official doc also answered your question about templates structure.
class app_directories.Loader
Loads templates from Django apps on the filesystem. For each app in
INSTALLED_APPS, the loader looks for a templates subdirectory. If
the directory exists, Django looks for templates in there.
This means you can store templates with your individual apps. This
also makes it easy to distribute Django apps with default templates.
The Two Scoops of Django is a great book. But you should read the official doc first.
About templates, as per Django official docs (https://docs.djangoproject.com/en/3.2/ref/templates/api/#loader-types):
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], #add this line
'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',
],
},
},
]