everybody! I want to access to constants value that I declare in my setting.py file to use in my template, but not in a template inside the app, I just want to use in my home template the template that I declare in my setting file.
CMS_TEMPLATES = (
## Customize this
('page.html', 'Page'),
('feature.html', 'Page with Feature'),
('homeTemplate.html', 'Home Template') // I want to use here
)
I found this example about the same problem in StackOverflow, but all case uses the variable inside apps not in top level.
How is the best way to use this value inside this template!!
I'd start by asking - why do you want to do that? It seems like an odd way of... adjusting the templates directories that you're using, i guess??
I wonder if you may have an XY problem. If you post what you're trying to achieve, that might be better than a specific solution to this specific problem.
Broadly though, you can only serve django variables (including from settings.py) inside a project or script that's using Django, or at least its environments. Doing from django.conf import settings imports the settings that are available at the highest level in the project, across all of the apps. Projects are laid out in this rough fashion.
myproject -
- myapp1
- myapp2
- myproject
- settings.py
- wsgi.py
- manage.py
As in this answer, For external scripts, you can still import the django settings thus:
import os
import django
from django.conf import settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
django.setup()
# now you can use settings.VARIABLE_NAME
But: this still won't get it into a template, because getting the variable from here into a template needs you to use the django engine to render a response.
If it's not being served by the django system, it's not a template, it's just a regular html file.
If it's a template in another app in your overall project, you would pass it as part of your context dictionary, as laid out in the docs on templates.
Related
I have a django model class with several images related to each instance.
Those images follow a certain pattern and can be determined by the name field of the model.
Those Images reside within the project static files folder.
So I have written a method for my model class to generate file paths for the images. It searches the static files folder for all files that follow the pattern *.jpg (the asterisks is necessary, because the filename has incrementing numbers).
Once it has found a file it transforms the absolute filesystem path into an url that is passed to a view and template via a list.
def getImages(self)
matches[]
for filename in fnmatch.filter(
os.listdir(os.path.join(settings.STATIC_ROOT_DIR,'images')), self.name + '*.jpg'):
matches.append(
os.path.join(settings.STATIC_URL, 'images', os.path.split(filename)[1]))
return matches
This method works fine, but doesn't leave me quite satisfied. Here are the reasons:
For development mode I am required to introduce a new variable called STATIC_ROOT_DIR, to obtain the path of the static files folder. I would like to use a consistent way to reference the static root folder for development and production. How can I achieve this? I would like to avoid development mode hackery as much as possible.
I have to build a URL by joining the static_url path with other strings that will eventually make up the URL for this static file. Is there a better way to construct URLs? Maybe some library function?
Last but not least: Is it good practice to do this in a model? Or is such a task better be done by a view?
There is a STATIC_ROOT variable in settings.py. Why not use it?
Personally, I follow your way - just concatenating paths. But just found a function for that:
from django.contrib.staticfiles.templatetags.staticfiles import static
print static('yourfile.jpg')
It works for me.
I think model is a good place for it. You store files in filesystem like you store model data in database. In other words, both of these are examples of storage which is a model level thing.
I would like to throw in another one:
Using STATIC_ROOT will break if you host your files externally.
You can use the django-storage-backend yourself (untested, just written):
from django.core.files.storage import get_storage_class
from django.conf import settings
def getImages(self)
static_storage = get_storage_class(settings.STATICFILES_STORAGE)()
directories, files = static_storage.listdir('images')
return [
static_storage.url('images/' + file)
for file in files
if file.startswith(self.name) and file.endswith('.jpg')
]
This will even return the correct URL if you use CachedStaticFileStorage or S3BotoStorage (from django-storages). And this will also be fine if you are in dev-mode.
I am not quite sure if my directory structure has the correct hierarchy and I decided to stop the development unless I will have it good.
I have order, customers, users .
So what I have is:
myproj
|-myproj
|-web_app
|---orders (with views.py, ajax.py)
|----templatetags
|---users
|---customers
|---search
|---static
|-----app
|-------_base
|---------css
|---------images
|---------js
|-------orders
|---------css
|---------images
|---------js
|-------customers
|---------css
|---------images
|---------js
|-------users
|---------css
|---------images
|---------js
|-----bootbox
|-----bootstrap
|-------css
|-------fonts
|-------js
|-----dajax
|---templates
models.py is in web_app directory, there are models common for all modules. My questions are:
1) What changes would you do in this structure? (static files for every module should be where?)
2) I have problem of inserting custom template tag defined in orders/templatetags/orders_extras.py from users template. How can I make some common templatetags for every "module" ?
Thank you.
This is explained in Django documentation very well. The good approach is:
Project
- App1
(Put app specfic templates to the app templates/App1/templates/App1/template files
- App2
- App3
- template for project (templates/ files)
Now, if you want template tags only for specific app create /templatetag directory under that app and do that.
For universal template tag do this:
Project
- templatetags
- __init__.py (Make sure it contains __init__.py)
- polltag.py
Explained here: https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
How can I make some common templatetags for every "module" ?
You should place it near the templates directory
myproj
|-myproj
|-web_app
|---templates
|---templatetags
|---orders (with views.py, ajax.py)
|----static
|-----static_files_here
dajax
Is this about dajax? If you are new to django, I recommend to get away from this stuff. You can just watch the issues list of this project to decide whether you should use it or not. The problem not only about that dajax is bad or good, but that these issues are being made by newbies that don't understand how ajax works, what are csrf tokens and so on.
When I started to learn django, I tried dajax too, but finally I have realized that you should understand how ajax and django works by their own and then try to combine them.
I was wondering if it is a good practice to have two views file. I have two views files. One to serve pages like about, home etc. The other is specific to the app I am building. I have the first one where I have my settings file.
It is better to make views as a package and then put the two files in there.
Example
- myapp/
- views/
- __init__.py
- first.py
- second.py
and in __init__.py
from .first import A, B
from .second import C, D
Nothing stops you from having 2 view files, but it becomes very unmanagable after a while. By creating a package, you have all views related code at one place, and easy to extend if need be.
I've inherited a Django application that I need to modify using a custom template filter. I'm absolutely new to Django and am quite mystified by it. I thought I had followed the instructions exactly, and also followed all the advice from other posts on the subject, but I still get an error when I include the following line in my template:
{% load mlgb_custom_filters %}
My directory structure is as follows:
mysite (i.e. the project)
__init__.py
mlgb/ (i.e. the app)
__init__.py
templatetags/
__init__.py
mlgb_custom_filters.py
The code of mlgb_custom_filters.py is as follows:
from django import template
from django.template.defaultfilters import stringfilter
register = template.Library()
#register.filter(name='fix_dashes')
#stringfilter
def fix_dashes( value ):
return value.replace( '--', 'DASH' )
if __name__ == "__main__":
testvar = fix_dashes( "ouch -- ow -- I hate django" )
print testvar
As you can see, I've added a 'name = main' section to let me run it in standalone mode, just to check that there are no errors in that particular file, and it's fine when run in standalone mode.
Based on someone else's advice, I've also tried importing it into another file, just to see whether there was an import error, and once again, it was fine if I added this to the end of settings.py (while using the dev server):
try:
import mlgb.templatetags.mlgb_custom_filters
except Exception, exc:
print 'error importing mlgb_custom_filters'
print exc
Also, INSTALLED_APPS in settings.py includes the line 'mysite.mlgb', and I have also tried putting just 'mlgb' instead of 'mysite.mlgb' there, as yet another person suggested. And I restarted the dev server every time I made a change.
I think I have tried every single suggestion that I have found on the web until now. Does anyone have any new ideas? Could it be anything to do with the fact that I have inherited a directory structure where the template directory is not within the same structure as the application, i.e. it is not under mysite? Scraping the barrel for ideas here! I hope someone can help.
OK, in the situation that I was in when first posting this question, it seems all I actually needed to do was touch a wsgi file under my appname/apache directory to force the application to be refreshed. Yesterday's initial answer was a red herring. Basically I should have touched the file myproject/myapp/apache/myapp.wsgi. Then maybe restart Apache for good measure? But the confusion was caused by the fact that apparently it wasn't enough either simply to restart Apache or to manually recompile the Python. In order to pick up my changes, seems like I needed to touch that wsgi file. Then all is well.
I can now post an answer to my own question thanks to the help of my colleague Masud Khokhar, whose brilliant detective work has saved the day. To recap, my application worked fine until I added a 'load' statement to one of my template files, to load a 'custom filters' module. Masud identified that now I needed to use a full/absolute path to the template file in urls.py instead of a relative one as I had before (and which worked before, until it needed to load the custom filters module). So, in urls.py, I had a section of code as follows:
url(r'^book/(?P<object_id>\d+)/$', 'list_detail.object_detail',
kwargs={
'queryset':Book.objects.all(),
'template_name' : 'mlgb/mlgb_detail.html'
},
name='mlgb_detail'
),
Instead of this:
'template_name' : 'mlgb/mlgb_detail.html'
I needed something like this:
'template_name' : '/THE_FULL_PATH/mlgb/templates/mlgb/mlgb_detail.html'
Made that change - sorted! Thank you once again, Masud.
Running through the djangobook (ver 2). I had a little trouble with template loading; my relevant filestructure:
testSite/urls.py
testSite/books/views.py
testSite/books/templates/
testSite/contact/views.py
testSite/contact/templates/
When I set-up a view for the books chapter (chap. 5), I was able to create a url in urls.py, point it to a view function in testSite/books/views, but when I called the template from that view function, I did not have to specify a directory - django knew it was in testSite/books/templates.
I tried doing the same thing for the contact form chapter (chap. 7), but this time it would not load the template - I had to go back to settings.py and explicitly place testSite/contact/templates into TEMPLATE_DIRS:
# testSite/settings.py
# ....
TEMPLATE_DIRS = (
'/home/chris/djcode/testSite/templates',
'/home/chris/djcode/testSite/contact/templates',
)
So - is there an obvious explanation as to why I need to point django to the contact/templates folder, but not the books/templates folder?
(If not, I can post more code - trying to keep it short)
You either did not add the contact application to your INSTALLED_APPS in settings.py OR you are trying to load the template from one application inside another application. The TEMPLATE_DIRS is where to look if it doesn’t find the template inside the same application as the views are loading from.
Probably because a Template Loader knows how to find it. The app_directories one will find the templates directory in each application.
django.template.loaders.filesystem.Loader will use the TEMPLATE_DIRS setting.
django.template.loaders.app_directories.Loader will find the templates directory in your installed apps.
If the first loader in the TEMPLATE_LOADERS setting can't find it, Django will ask the next to see if it can find it.
How are you telling your views which templates you're using?
I expect your books app is in INSTALLED_APPS, but contact is not.