Django could not load template tag - django

I have created a templatetags folder inside my application and inside a file named posts.py, I have written the following code;
from django.template import Library, Node
from advancedviews.models import Post
register = Library()
class AllPost(Node):
def render(self,context):
context['all_posts'] = Post.objects.all()
return ''
def get_all_posts(parser,token):
return AllPost()
get_all_posts = register.tag(get_all_posts)
Now, I try to load this template tag inside my template;
{% load get_all_posts %}
But this gives me with error, 'get_all_posts' is not a valid tag library: Template library get_all_posts not found, tried django.templatetags.get_all_posts,django.contrib.admin.templatetags.get_all_posts
What is the error in this template or have I missed something here.

With load you need to use the name of the library, not the tag - so posts in your case.
(I assume you also have a blank __init__.py in the templatetags directory, and that the application is in INSTALLED_APPS).

suppose you have the following structure:
-- Application_Name
-------templatetags
--------------__init__.py
--------------templates_extras.py
-------__init__.py
-------settings.py
-- manage.py
You have to make sure of the following:
your application itself inside which your "templatetags" is resident is actually installed in INSTALLED_APPS in settings.py (e.g. "Application_Name")
your tag module itself that exists inside "templatetags" is already installed in INSTALLED_APP in settings.py (e.g. "ApplicationName.templatetags.tempaltes_extras")
keep sure you have "__init__.py" under templatetags directory
you have to restart the server
In some cases you have to remove all generated *.pyc if it did not work then retry again

Related

pass data from Django view to react

I have a django view that returns a variable in order to be rendered in template
return render_to_response('index.html', {
'courses': courses})
I'm using ReactJS to render the index.html file, but I'm not sure whether i have to point to index.html in my view or the ReactJS file.
If I have to point to index.html how can I use the courses variable with React ?
Update
the variable courses that i'm passing is of type dictionnary
Templates processing is anterior to any sort of JavaScript interpretation. This means that you will have to, in some sense, emulate its hardcoding beetween the js tags.
First, know that the python dictionary is likely to be corrupted when received on the client side. To prevent this, you may want to send it as a json object. Which means that, in you script views.py, you will have to json.dumps your dictionary. As follows
from django.shortcuts import render
import json
#...
#...
return render(request,
'your_app/index.html',\
{'courses': json.dumps(courses)}\
)
Note that I use render instead of render_to_response, because render is a brand spanking new shortcut for render_to_response in 1.3 that will automatically use RequestContext
Also, note that you do have to point to your index.html, but the exact path depends on the strucutre of your project. Above, I assume you followed the recommended django project layout, i.e.
myproject/
manage.py
your_project/
__init__.py
urls.py
wsgi.py
settings/
__init__.py
base.py
dev.py
prod.py
your_app/
__init__.py
models.py
managers.py
views.py
urls.py
templates/
your_app/
index.html
[...]
Then, on the html side,
...
<script>
var courses = {{courses|safe}}
// working with the variable courses
</script>
...
Now, you can do what you want with it, be it with ReactJS library.

'custom_filters' is not a valid tag library

I'm trying to create custom filters, and I've followed the steps in the Django documention.
However, when I load the template that loads the filters the following error is thrown:
'custom_filters' is not a valid tag library
...which refers to the line below in the template:
1 {% extends 'shared/base.html' %}
2 {% load custom_filters %} <--- the error
3
4 {% block title %}
5 Showing project {{project}}
6 {% endblock %}
The file structure:
project/
...
...
models.py
views.py
templates/
templatetags/
__init__.py
custom_filters.py
custom_filters.py:
from django import template
register = template.Library()
#register.filter(name='ownership')
def ownership(project, user):
return project.added_by_user == user
So, by some reason Django can't find the custom_filters file as it seems, even though I have done everything as one should (as far as I know).
What am I doing wrong?
NOTE: Of course I've tried to restart the server.
Template tags folder must be beside of templates folder, views.py, models.py, ...
//Don't forget also to put __init__.py outside the templatetags,
#register.simple_tag
def ownership(project, user):
return project.added_by_user == user
If your App name is MyApp and your tag folder name is templatetags then in settings.py you should have :
INSTALLED_APPS = [
'MyApp',
'MyApp.templatetags'
]
Both your app and your tag folder which is under your app package
Django Project are needed there.
-> MyApp
---> models.py
---> views.py
---> templatetags
-----> __init__.py
-----> app_filters.py

Django on APP Engine - error redirecting a URL path to an existing function in views.py (on urls.py)

I'm getting an error when I try to redirect a URL path to an existing function inside of a views.py file.
I realize where the problem is, but I cannot figure out how to solve it.
I have the following structure of folders on my project:
my_app_gae
app.yaml
main.py
settings.py
urls.py
my_app_django (<-- here is my django project)
dashboard
views.py
models
models.py
The problem comes here:
when I edit the urls.py file, when I try to redirect a specific URL path to an existing function inside of views.py (landing), I recieve the following error:
Request Method: GET
Request URL: http://localhost:8090/landing/
Exception Type: ImportError
Exception Value: No module named my_app_django
The value of my Python Path is: V:\Python~1\my_app_gae (the place where the structure of folders I wrote before is).
The url.py value that I'm trying to execute is:
from django.conf.urls.defaults import *
from my_app_django.dashboard.views import landing
urlpatterns = patterns(
'',
(r'^landing/$', landing),
)
If I copy the views.py file directly on the my_app_gae directory it works. The problem comes when the views.py file is inside of other directories.
Thanks a lot.
Regards
To be recognized as a Python package, you need empty files named __init__.py in each subdirectory.

Django view - load template from calling app's dir first

I try to keep a somewhat consistent naming scheme on my HTML templates. I.e. index.html for main, delete.html for delete page and so forth. But the app_directories loader always seems to load the template from the app that's first alphabetically.
Is there any way to always check for a match in the calling app's templates directory first?
Relevant settings in my settings.py:
PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))
TEMPLATE_LOADERS = (
'django.template.loaders.app_directories.load_template_source',
'django.template.loaders.filesystem.load_template_source',
)
TEMPLATE_DIRS = (
os.path.join(PROJECT_PATH, 'templates'),
)
I've tried changing the order of TEMPLATE_LOADERS, without success.
Edit as requested by Ashok:
Dir structure of each app:
templates/
index.html
add.html
delete.html
create.html
models.py
test.py
admin.py
views.py
In each app's views.py:
def index(request):
# code...
return render_to_response('index.html', locals())
def add(request):
# code...
return render_to_response('add.html', locals())
def delete(request):
# code...
return render_to_response('delete.html', locals())
def update(request):
# code...
return render_to_response('update.html', locals())
The reason for this is that the app_directories loader is essentially the same as adding each app's template folder to the TEMPLATE_DIRS setting, e.g. like
TEMPLATE_DIRS = (
os.path.join(PROJECT_PATH, 'app1', 'templates'),
os.path.join(PROJECT_PATH, 'app2', 'template'),
...
os.path.join(PROJECT_PATH, 'templates'),
)
The problem with this is that as you mentioned, the index.html will always be found in app1/templates/index.html instead of any other app. There is no easy solution to magically fix this behavior without modifying the app_directories loader and using introspection or passing along app information, which gets a bit complicated. An easier solution:
Keep your settings.py as-is
Add a subdirectory in each app's templates folder with the name of the app
Use the templates in views like 'app1/index.html' or 'app2/index.html'
For a more concrete example:
project
app1
templates
app1
index.html
add.html
...
models.py
views.py
...
app2
...
Then in the views:
def index(request):
return render_to_response('app1/index.html', locals())
You could even write a wrapper to automate prepending the app name to all your views, and even that could be extended to use introspection, e.g.:
def render(template, data=None):
return render_to_response(__name__.split(".")[-2] + '/' + template, data)
def index(request):
return render('index.html', locals())
The _____name_____.split(".")[-2] assumes the file is within a package, so it will turn e.g. 'app1.views' into 'app1' to prepend to the template name. This also assumes a user will never rename your app without also renaming the folder in the templates directory, which may not be a safe assumption to make and in that case just hard-code the name of the folder in the templates directory.
I know this is an old thread, but I made something reusable, that allows for simpler namespacing. You could load the following as a Template Loader. It will find appname/index.html in appname/templates/index.html.
Gist available here: https://gist.github.com/871567
"""
Wrapper for loading templates from "templates" directories in INSTALLED_APPS
packages, prefixed by the appname for namespacing.
This loader finds `appname/templates/index.html` when looking for something
of the form `appname/index.html`.
"""
from django.template import TemplateDoesNotExist
from django.template.loaders.app_directories import app_template_dirs, Loader as BaseAppLoader
class Loader(BaseAppLoader):
'''
Modified AppDirecotry Template Loader that allows namespacing templates
with the name of their app, without requiring an extra subdirectory
in the form of `appname/templates/appname`.
'''
def load_template_source(self, template_name, template_dirs=None):
try:
app_name, template_path = template_name.split('/', 1)
except ValueError:
raise TemplateDoesNotExist(template_name)
if not template_dirs:
template_dirs = (d for d in app_template_dirs if
d.endswith('/%s/templates' % app_name))
return iter(super(Loader, self).load_template_source(template_path,
template_dirs))
The app_loader looks for templates within your applications in order that they are specified in your INSTALLED_APPS. (http://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types).
My suggestion is to preface the name of your template file with the app name to avoid these naming conflicts.
For example, the template dir for app1 would look like:
templates/
app1_index.html
app1_delete.html
app1_add.html
app1_create.html

Problem loading custom template tags (Error: No module named x)

I am currently writing a few custom template tags but for some reason they will not load. My directory structure is as follows:
MyProj
|
----MyApp
|
|----templatetags
|
|----myapp_tags.py
|----__init__.py
In myapp_tags.py
from django.template import Library, Node
from myproj.myapp.models import Product
register = Library()
class LatestProductsNode(Node):
def render(self, context):
context['recent_products'] = Product.objects.all()[:5]
return ''
def get_latest_products(parser, token):
return LatestProductsNode()
get_latest_products = register.tag(get_latest_products)
In settings.py
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
'myproj.myapp',
)
In the Template
{% load myapp_tags %}
The error i get when trying to load the page:
Exception Type: TemplateSyntaxError Exception Value:
'myapp_tags' is not a valid tag library: Could not load template library from django.templatetags.myapp_tags, No module named myapp_tags
in settings.py, you should never name the project 'myproj' explicitely. In INSTALLED_APPS, just use 'myapp'. Also, you should have this :
TEMPLATE_LOADERS = (
'django.template.loaders.app_directories.load_template_source',
)
And be sure to have an __init__.py in the myapp folder as well as in templatetags.
Use manage.py shell then from myapp.templatetags import myapp_tags to find out if theres any python error in the myapp_tags.py file.
Also, be sure that myapp_tags.py file name doesnt conflicts with another folder/file in your project.
Hope this helps.
One thing that's tripped me up is that the magic importing of templatetags bypasses the automatic reloading of the development server.
If the following works in manage.py shell
>>> from django.templatetags import myapp_tags
>>>
Then everything is actually working and you just need to reload the development server. If on the other hand you get an ImportError then something is wrong and you should check your INSTALLED_APPS, that you have an __init__.py file in the templatetags directory and all the other things suggested in the other answers.
This will probably only apply to a tiny fraction of the people who experience template tag loading problems, but this is the second time I've arrived at this question in as many weeks and both times it's just taken restarting the development server to get things working.
Some reasons:
due to error in templatetgs code.
If you have used model import in templatetags
For #2, for example. If you are doing:
from your_app2.models import model
This will go wrong, so instead above, you should do
from your_project.your_app2.models import model
It worked me this way.
I just came across the same problem in Django 2 and realized that the custom template tag files must have unique names across all of your project apps.
The problem is that nyapp_tags is not at the top level of an installed project. If you put myproj.myapp.templatetags in INSTALLED_APPS, you should be fine.