Is there a naming convention for Django project/configuration directory? - django

I'm referring to directory holding settings.py and wsgi.py (Two Scoops of Django refers to this as the 'configuration root', for what it's worth)
I've seen people name this directory after the actual project name (the official Django tutorial does this) but that leads to a redundant/confusing directory structure like the following:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
app1/
app2/
seems like it'd be more clear to have something like the following:
mysite/
manage.py
conf/
__init__.py
settings.py
urls.py
wsgi.py
app1/
app2/
I see that there is already a question about Django app naming conventions but couldn't find anything regarding the project/conf directory.
To be clear, I'm asking about what to name the directory, not formatting conventions (underscores, lowercase vs. upper, etc.).

There is some good discussion on this topic here. Some generic options are project, config, core, base. I'm partial to "project" (/mysite/project/settings.py etc). To set up a new project like this, cd into your empty base directory and run django-admin startproject project ..
I've never been a fan of the default convention. It seems redundant and often conflicts with what I want to name my "main app". For example, I want to make a time tracking site, so I call my project "timers" (/timers/timers/settings.py etc). But now I can't start an app called timers, which is the best name for the app where I keep the timer model etc. If I name my project "project" then I can still have an app called "timers".
timers/
manage.py
project/
settings.py
timers/
models.py

Generally you should use the pattern which you use for any package or module.
1. small letter
2. Underscore (_) if needed.
If you don't want to use redundant name you just add dot(.) after a space after roject creation command.
django-admin.py startproject myproject .

Related

Do I need to place __init__.py in each directory in a directory tree leading to my class?

I'm building a Django project with Python 3.6. I have created this directory structure ...
project
- manage.py
- scripts
- run_commands.py
- commons
- util
- __init__.py
- my_class.py
The contents of init.py are
from . import my_class
In another class, I attempt to import my MyClass like this
from commons.util import MyClass
but I'm getting this error
ModuleNotFoundError: No module named 'commons'
Am I creating my init.py properly?
It looks like the problem is that MyClass is not located in commons.util, because you only imported the module named my_class, not the class itself.
Instead the file commons/util/__init__.py should contain the following import:
from .my_class import MyClass
I don't think this will solve your problem, because you would be getting a different error than the one shown, but you will get errors for this eventually.
Update
First, I'd recommend reading this answer for a good explanation for how imports work in python.
Basically, when you execute from commons.util import MyClass, the interpreter scans the contents of sys.path for a module named commons.
I assume you didn't set sys.path to include your project folder, hence the ModuleNotFoundError.
TLDR; you have 2 options:
Manually set sys.path in run_commands.py to check your project folder (Don't do this!)
Use Django's Command class
To use Django's Command class, you will need to adjust your project folder similar to the following:
project
- manage.py
- commons
- management
- commands
run_commands.py
- util
- __init__.py
- my_class.py
Now in run_commands.py:
from django.core.management.base import BaseCommand
from commons.util import MyClass
class Command(BaseCommand):
def handle(*args, **options):
print("handling", MyClass)
You can execute the new command with the following:
python3 manage.py run_commands
It used to be the case that yes, you need to put an __init__.py in every directory that is going to be treated as a python module as without an __init__.py python wouldn't look inside that directory for importable code.
- project
- __init__.py
- commons
- __init__.py
- util
- __init__.py
- my_class.py
But as Reinstate Monica points out below this is no longer true as of Python 3.3+. So, depending on your version of Python you will need to make an informed decision.
Note, you might or might not need an __init__.py in the root project directory (if you need them at all), it depends if it has definitions that are part of the source tree. But you won't need it if it's just a container, like you see in the way most Django projects are organised, for example.
https://docs.python.org/3/tutorial/modules.html
https://docs.python.org/3/tutorial/modules.html#packages

Django makemessages not working for JS files

My setup
settings.py
INSTALLED_APPS = (
...
'myprojectname',
...
)
STATIC_ROOT = '/var/www/a_valid_path/'
LOCALE_PATHS = (
os.path.join(BASE_DIR, "locale"),
)
urls.py
js_info_dict = {
'domain': 'djangojs',
'packages': ('myprojectname',),
}
urlpatterns = patterns('',
...
url(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
...
)
My project structure is as follows:
|- projectname
|--- app1
|--- app2
|--- manage.py
|- virtualenv
|- static
|--- js
|--- css
I also have the locale folder in the root folder of my project, where manage.py is located.
What I'm doing
Simply running:
./manage.py -l ro -d djangojs
My problem
It's not working. No .po file is being generated. Server-side translation works, however (views + templates). I've followed all advice, and still nothing. Even tried to create the djangojs.po file myself to see if Django deletes it, or does something with it -- nope.
No error is generated, just processing locale ro is shown (for a really short time -- too short if you ask me), and that's that. Any help?
Edit: Forgot to mention that my folder containing the JS files is not inside each Django app, but in a separate location. Still, shouldn't Django look inside the STATICFILES_DIRS?
Django's makemessages only will make messages from files that are in on one of your TEMPLATE_DIRS. So any files you want to translate need to be in one of those directories.
You can do that in one several ways:
Place the *.js files in one of your TEMPLATE_DIRS as is
In-lining your JS in the html files
Place all the strings that need translation in data-attributes on the dom and grab them from the dom via JS
Are you running makemessages from a directory parent of the ones containing your JavaScript files?
Do your JavaScript file names ends with a .js?
Do you either use django.gettext('string') or _('string') to mark strings requiring translations?
I've experienced the same issue. I've discovered that the issue is reported in the Django ticket #23717: https://code.djangoproject.com/ticket/23717
Fixes are in upcoming stable 1.7.2 version: https://docs.djangoproject.com/en/1.7/releases/1.7.2/
I've installed 1.7.2 and confirmed that the issue is fixed.
I had the same problem when using the Django i18n, after many times trying, I finally got the correct answer: we need to put the .js files into the project directory, which was specified when we assign 'js_info_dict'.
But usually we put the JavaScript files in the same level catalog as project, so there is the problem. (we don't need to put the JavaScript files into templates directory).

Changing Admin Templates - Django tutorial 2

This question was answered more or less here but it didn't work to me and as far I can see more people have the same problem.
In my settings.py I have this lines:
#TEMPLATE_DIRS = [os.path.join(BASE_DIR,'..', 'templates'),]
TEMPLATE_DIRS = ("/root/GODJANGO/thedjango/django_project",)
The comented line didn't work. It works if I write the full path but It's not professional and I don't wanna have problems when I three months later I migrate my server because I will not remember this thing.
Can anybody tell me how to write My Path correctly ("dynamically, I mean")
Please tell me where is the best directory to put my templates folder and also my admin templates folder
If you have the following project layout:
manage.py
myproject/
settings.py
urls.py
wsgi.py
templates/
admin/
app1/
app2/
Then you can dynamically set your template directory by putting the following in your settings.py:
...
SETTINGS_PATH = os.path.abspath(os.path.dirname(__file__))
TEMPLATE_DIRS = (
os.path.join(SETTINGS_PATH, "templates")
)
...
if your template folder is in the parent folder to the settings.py you will need something like:
...
SETTINGS_PATH = os.path.abspath(os.path.dirname(__file__))
PROJECT_FOLDER = (os.path.split(SETTINGS_PATH))[0] # get the parent directory
TEMPLATE_DIRS = (
os.path.join(PROJECT_FOLDER, "templates")
)
...
As you can see, we are manually traversing the file tree to find where the templates folder is and assigning it dynamically.
The best place for your templates folder depends on your project layout (< 1.4 or >= 1.4) but it would be probably safest to say that it should be alongside your settings.py file. Your admin template folder will go inside your base templates folder: templates/admin/.
What are you trying to do with this paramater ".." in the commented line?
if it is means parent directory you can use os.path.dirname(BASE_DIR)
Second part:
It depends you or team work with; i love to keep templates directory in every app's directory (and if you do like this you don't need to define TEMPLATE_DIRS). I mean if i have templates of news app, they goes ../news/templates/. But this time my friend (front-end developer) says i cant find them, can we put all of them in one place?
so i put them in one directory with sub directories (../templates/news/). This main templates directory is in main project directory (near the manage.py file). And if you add this main directory to INSTALLED_APPS (because its kind an app) you don't need to define TEMPLATE_DIRS too. And even you can create models.py admin.py files here.
Considering the second part of your question and according to this the safest part for your templates is to create a templates dir under your projects main directory (e.g. blog).
As for the first part i am not sure.

Django: How to specify path to settings file

I know this question has already been asked multiple times but I still can't seem to find a solution that works for me. My Django project folder looks like this:
my_project
__init__.py
manage.py
my_first_app
my_second_app
core
Now the "core" folder looks like this:
__init__.py
some_other_stuff.py
settings
__init__.py
prod.py
dev.py
local.py -> dev.py
local.py is a symbolic link pointing to the right settings file, dev.py on my machine, prod.py in production.
Here's my problem: when I try to use manage.py, I get a weird error ImproperlyConfigured: The SECRET_KEY setting must not be empty. When I pass the path to the settings file local.py as an argument (--settings=core.settings.local) it runs fine. I figured the problem was that Django didn't know where to look for the settings file. How can I tell him (her?) where to look?
I already tried exporting the path to the env (export DJANGO_SETTINGS_MODULE=core.settings.local) and setting the PYTHONPATH to the parent directory, to no avail.
The primary use of __init__.py is to initialize Python packages. The easiest way to demonstrate this is to take a look at the structure of a standard Python module.
package/
__init__.py
file1.py
file2.py
As you can see in the structure above the inclusion of the __init__.py file in a directory indicates to the Python interpreter that the directory should be treated like a Python package
__init__.py can be an empty file but it is often used to perform setup needed for the package(import things, load things into path, etc).
One common thing to do in your __init__.py is to import selected Classes, functions, etc into the package level so they can be convieniently imported from the package.
In our example above we can say that file.py has the Class File. So without anything in our __init__.py you would import with this syntax:
from package.file import File
However you can import File into your __init__.py to make it available at the package level:
# in your __init__.py
from file1 import File
# now import File from package
from package import File
Source
So for conclusion, when you call import in __init__.py in a package mypackage, it's like you use package as a simple python file, that's what my solution do:
from .local import * in __init__.py
I haven't use this before in the settings case but I use it when I wanna to subdivide my models in a Django app, models.py --> models package, ./manage syndb doesn't discover my models declared, I found so this solution that's similar. You can find more details here
Last thing, I'm sure there's others solution to your problem, but this can be the most simple.
Good luck
You are in import hell somewhere. Had this problem too one time. The only way to find out where the root of your problem is, might be to disable all apps, try starting the server, enable the first app, start the server, enable the next etc.
BTW: your project layout should not be used from Django 1.4 onward. https://docs.djangoproject.com/en/dev/releases/1.4/#updated-default-project-layout-and-manage-py
I'd try to use the new layout and hope that it 'just works'.
I think you need to change the name of the file that the manage.py is looking for.
try:
imp.find_module('settings') # Assumed to be in the same directory.
except ImportError:
import sys
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n" % __file__)
sys.exit(1)
If you had the settings.py file in the same directory simple changing the 'settings' to 'local' would have worked.
But, since you have it in a different directory, I think you need to configure the settings. Refer to this: https://docs.djangoproject.com/en/dev/topics/settings/#using-settings-without-setting-django-settings-module
from django.conf import settings
settings.configure(DEBUG=True, TEMPLATE_DEBUG=True,
TEMPLATE_DIRS=('/home/web-apps/myapp', '/home/web-apps/base'))
Hope that helps.

Strange new directory structure in Django-1.4.1?

I've just installed the latest version of Django (1.4.1) on Ubuntu 12.04. The new docs and everything else I've been able to find seems to think the directory structure should be as follows:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
However, running $ django-admin.py startproject mysite resulted in the following directory structure:
mysite/
__init.py__
manage.py
settings.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
templates/
urls.py
There seems to be little difference between mysite/urls.py and mysite/mysite/urls.py, the difference being in line 1 of the files, where the mysite/urls.py import statement begins from django.conf.urls.defaults instead of from django.conf.urls. There is similarly little difference between the two settings.py files.
My question is:
Is this the result of a bug
Did I accidentally download the trunk which is displaying (for some reason) an incorrect version number
Or is it supposed to be like this, and if so, why, what's the difference between the similar files, and how should I use them?
EDIT: Oberon's answer solved the problem for me (thanks!), but I'd still be interested in knowing what the problem was in the first place, if anybody has any ideas.
I've met the same problem with it, and what I do is to remove django and reinstall it
And it works like the first one you've shown.