What is the reason for nested template directory structure? - python

The django template folder requires creating a subfolder with the name of the app which then contains the template files. Why is this necessary, when python manage.py collectstatic can infer this information while traversing all directories? It seems very redundant.

First of all, Django does not require this specific folder structure for templates to work, it is just a stablished pattern to do so. And, of course, it has a rationale, as pointed in the official doc:
Template namespacing
Now we might be able to get away with putting our templates directly
in polls/templates (rather than creating another polls subdirectory),
but it would actually be a bad idea. Django will choose the first
template it finds whose name matches, and if you had a template 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 templates inside another directory named for
the application itself.
You can reference to this question or that another for concrete cases.
In a nutshell, by following this pattern you can have your templates organized in 2 groups:
templates related to your specific site or project can live inside the directory pointed by the TEMPLATES['DIRS'] setting;
templates related to a specific app, that could be served as is if you make your app pluggable, should live inside './appname/templates/appname/' (and TEMPLATES['APP_DIRS'] must be True). This way you avoid name conflicts between files inside this folder anf files from outside.

Related

How to understand Django templates?

Here is official Django tutorial, templates section:
First, create a directory called templates in your polls directory. Django will look for templates in there.
Within the templates directory you have just created, create another directory called polls, and within that create a file called index.html. In other words, your template should be at polls/templates/polls/index.html. Because of how the app_directories template loader works as described above, you can refer to this template within Django simply as polls/index.html.
...and explanation of "namespacing":
Now we might be able to get away with putting our templates directly in polls/templates (rather than creating another polls subdirectory), but it would actually be a bad idea. Django will choose the first template it finds whose name matches, and if you had a template 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 templates inside another directory named for the application itself.
but different app has different absolute path of templates directory. Is there any problems with such project structure?
my_project
|
+--first_app
| |
| +--templates
| |
| +--index.html
| +--foo.html
+--second_app
|
+---templates
|
+index.html
We have my_project/first_app/templates/index.html and
my_project/second_app/templates/index.html - no collision.
Django will choose the first template it finds whose name matches
I suppose, Django using relative path to compare insted of absolute. What's the point of it? Is there any hidden profits?
I just diving into Django and that seems like violation of DRY principle. So, why such elegant and pythonic framework uses such weird convention?
Everything under templates/ is grouped into one list. They are "put over one another" in the order of your INSTALLED_APPS setting (the bottommost first).
In your case, if INSTALLED_APPS = ['first_app', 'second_app'], django will know of two templates:
index.html from first_app, which has overwritten the similary-named one from second_app.
foo.html from first_app.
So... everything below templates/ in each of your apps is grouped together. Which is why it is good to use the namespacing mentioned in the docs. So second_app/templates/second_app/index.html, for instance.
That Django allows you to overwrite templates is handy: you can overwrite the default login page, for instance.

What happens when you don't define STATICFILES_DIR in django?

I use django and my application works, when I change the style.css the app changes etc.
However, I recently found out that I didn't define STATICFILES_DIR, I only defined
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
Which is only for collectstatic.
But now I'm wondering, how does django know where to look for the static files?
Specifically in the polls/static/polls directory?
Django will look for a directory named static in each of your apps by default. More on this later.
From the documentation:
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.
The key part being
...Django will use the first static file it finds whose name matches...
There are Django libraries called "static file finders" that help with this process. You can configure them by modifying the installed apps in your Django configuration file.
According to the documentation, they're actually undocumented, because they are considered private. However, you can look at the source code for those "finders" on GitHub.
Django projects are composed of modules called apps. Each app contains some default files when you generate it. Although there is configuration, there's plenty of convention about Django too. For example, the views.py file. Another such convention is your app's static directories folder.
Your STATICFILES_DIR array allows you to add additional places for you to put your static files. This is useful, as you'll see when you prepare to deploy, because of the way Django handles static files in a real-world environment.
It's totally optional, but it's there to make your life easier later.

Adding Reference Without Using add_static_view

I'm building an application in Pyramid and utilizing Jinja2 templates and traversal routing. In order to wire my view-callables with the templates I am using, I want to be able to reference my templates using the webapp:templates prefix. As an example:
#view_config(name='about-us', renderer='webapp:templates/pages/about-us.html', context=Root)
def static_pages(context, request):
... //more code
This decouples where the templates live from whats using them. In order to make the above functional, though, I had to put this inside the __init__.py in my webapp root folder:
config.add_static_view(name='templates', path='webapp:templates', cache_max_age=3600)
The add_static_view() causes the webapp/templates folder to be referenced as webapp:template in other configurations. However, it also makes it viewable from a url such as http://0.0.0.0:6543/templates/<some template file>. Is there a way to achieve the former goal without allowing the latter visibility as a static page?
add_static_view() is not supposed to cause the webapp/templates folder to be referenced as webapp:template in other configurations, if it does that it's just due to a weird side-effect.
The package:path syntax works because Pyramid uses pkg_resources API to resolve the paths. Here are some details.
This means that, in your example, webapp should be a python package located somewhere your app can find it.

multiple Django projects in one directory

Iam trying to create multiple projects into one existing django project.
The directory should be set up as follows
directory picture
Is it possible to use this direcory without using multiple databases and config files. Everything in a single django instance?
If so, how?
The problem is, i cant reach the moduls in my mainproject urls.py. They cant be found.
thanks :)
Why would you want to do this? If you need two different django projects, keep them as different django projects.
It is different if you want to use the same database and reuse some of your existing apps.
For the first, you can set that in your settings.py file of each project to point to a common database, you can even manage to share only some tables in a common database and keep the others as a separated database for each project (there are some limitations with that approach though). Check django multidb docs for more info.
For the second, you can create a folder containing your django apps (with their models definitions, views, admin and whatever you need) and import them in the settings.py. An example:
APPS_PATH = "/django/apps/folder/"
sys.path.insert(0, APPS_PATH)
INSTALLED_APPS = (
...
custom_app1,
custom_app2,
)
You may also want to check django sites.
Hope it helps.

django package organization

I plan to build my project in Django framework. However, I noticed that all Django packages have models.py file. Now, let say I have a set of general purpose functions that I share between several apps in the project and I plan to put these functions definitions in a separate package (or app for that matter?). So, should I create an app "general" and copy-paste these functions into the models.py file? Or can I just create a general.py file in the "general" app directory and leave models.py empty? What is the "Django" way to do that?
Thanks.
models.py file is used to define the structure of database. So you should leave it for defining your database entries. You can make an app named generals and put general.py in that app, and from there you can use it by calling it in any app.
I usually create a utils.py file under my main app that is created from the django-admin.py when starting the project.
I plan to put these functions definitions in a separate package (or app for that matter?)
Before you decide to make this an app (and if you do decide to make it an app), I recommend you take a look at James Bennet keynote on Developing reusable apps and hist post on laying out an application. From one of his slides:
Should this be its own application?
Is it orthogonal to whatever else I’m doing?
Will I need similar functionality on other sites?
Yes? Then I should break it out into a separate application.
If you're cramming too much functionality in one single general purpose app, it might be better to split your general purpose app into multiple reusable apps.
Going back to your original question, Django is expecting a models.py file in every app. So you must have the file even if it's empty.
Inside your models.py, you should only have the application’s model classes. So, you wouldn't be following a best practice if you put inside models.py some miscellaneous code you want to reuse.
From the laying out an application post I mentioned before:
At the application level, I usually drop in a few more files depending on exactly what the application is going to be using:
If the application defines any custom manipulators, I put them in a file called forms.py instead of in the views file.
If there are multiple custom managers in the app, I put them in a file called managers.py instead of the models file.
If I’m defining any custom context processors, I put them in a file called context_processors.py.
If I’m setting up any custom dispatcher signals, they go in a file called signals.py.
If the application is setting up any syndication feeds, the feed classes go in a file called feeds.py. Similarly, sitemap classes go in sitemaps.py.
Middleware classes go in a file called middleware.py.
Any miscellaneous code which doesn’t clearly go anywhere else goes in a file or module called utils.
All of this does not answer directly your original question:
can I just create a general.py file in the "general" app directory and leave models.py empty?
But I hope this gives you additional information to make a decision that better fits your project and requirements.

Categories