I try to use assignment_tag from django docs: https://docs.djangoproject.com/en/1.4/howto/custom-template-tags/#howto-custom-template-tags-simple-tags
Test project:
mysite/
manage.py
polls/
views.py
...
mysite/
...
templates/
polls/
detail.html
In polls/views.py:
from django.template import Library
register = Library()
#register.assignment_tag
def get_text():
return 'TEST TEXT'
Then I add code to templates/polls/detail.html
{% get_text as text %}
<p>The text is {{ text }}.</p>
But this is not work, I understand that get_text not visible, but I do not know how to do it right.
Your template tag should not go in the views.py file. You need to create a module in your app's templatetags directory. Have a look at the code layout docs for template tags.
Secondly, remember to load your tag in the template before you use it, with the {% load %} tag.
If you still have problems, update your question and include the full traceback -- 'template syntax error' isn't enough information for us to work out what's going on.
Related
I am trying to create an eCommerce app and have the cart option in that. However, on every page of the site (or every view), I always type the code...
context = {
"no_in_cart":no_of_items_in_cart(request)
}
Where no_of_items_in_cart is a function to find the number of items in the cart.
But I feel this is a waste of code and may have several inefficiencies.
And also I am not sure on how I can send this code through auth_views, such as login or register views.
Any help would be greatly appreciated.
Thanks!
EDITED CONTENT
So now in my tag_name.py I have the code..
from django import template
register = template.Library()
#register.inclusion_tag("base.html")
def a_tag_name(request):
return {"no_in_cart":no_of_items_in_cart(request)}
def no_of_items_in_cart(request):
total = 0
for item in request.session.get('order'):
total += item["quantity"]
return (total)
And in my base.html I have the following tags at the very top of the page...
{% load static %}
{% load tag_name %}
{% a_tag_name request %}
<!DOCTYPE html>
<html lang="en">
<head>
...
And I don't repeat the tags {% load tag_name %} or {% a_tag_name request %} in any other sub-template.
However, by doing so, I am thrown with an error...
Exception Type: AttributeError
Exception Value:'str' object has no attribute 'session'
And it highlights the line {% a_tag_name request %}.
Any idea on how to figure this out?
Thanks!
If I am understanding your question correctly. You are displaying the "no_in_cart" in many pages where you have to pass this context variables every time you render a page. You want to have a way where the context variable(no_in_cart) can be used in many pages but you do not have to pass it every time.
This can be done using template tags. Not sure if its efficient.
If you want I can give a sample code to work with template tags.
Create Files as described below:-
Appdirectory
templatetags
__init__.py
tag_name.py
models.py
views.py
In tag_name.py:-
from django import template
register = template.Library()
#register.inclusion_tag("condition.html")
def a_tag_name(request):
return {"no_in_cart":no_of_items_in_cart(request)}
Then in condition.html:-
# some django template code(html) if required
{{no_in_cart}}
Then finally in the page where you want to use this.
At the top load the tags first
{% load tag_name %}
then put this the desired place
{% a_tag_name request %}
Location of files should be as specified. You can rename everything except templatetags. Also run manage.py collectstatic.
Hope it helps.
If you want to learn more about tags refer:-
https://docs.djangoproject.com/en/3.1/howto/custom-template-tags/
https://medium.com/#hiteshgarg14/creating-custom-template-tags-in-django-application-7bd1dcfeb144
Summary
I've been trying to get a custom tag working in Django, but seemingly it wont register correctly.
The index file looks to load correctly, it just complains about the tag not being registered correctly.
What I've done right now is just to put the .py file where I register the tag inside an app that is in the django installed apps part.
Should I be doing something else to ensure the tag registers properly?
Further info
The error I get:
Invalid block tag on line 1: 'show_loans'. Did you forget to register
or load this tag?
The view where I call the tag
index.html
{% show_loans %}
The python file where i try to register the tag
loansTable.py
from .models import Loan
from datetime import datetime
from django import template
register = template.Library()
#register.simple_tag('loansTable.html')
def show_loans():
l1 = Loan()
l2 = Loan()
l1.loanedDate_date = datetime.now
l2.handinDate_date = datetime.now
l2.loanedDate_date = datetime.now
l2.handinDate_date = datetime.now
loans2 = { l1, l2 }
return {'loans': loans2}
loansTable.html
<ul>
{% for loan in loans %}
<li> {{ loan }} </li>
{% endfor %}
</ul>
Folder structure:
-app
--templates
---customTemplates
----index.html
----loansTable.html
--loansTable.py
Thanks for your help.
You don't need to register your tag to a template. You just need to load it from there. Which you are already doing.
Therefore just replace:
#register.simple_tag('loansTable.html')
With this:
#register.simple_tag
You also need to put your custom tags in a templatetags directory. From the docs:
In your index.html you must load template tags by file name where you have registered your template tags.
i.e. if you registered tag inside custom_tags.py file
{% load custom_tags %}
The app should contain a templatetags directory, at the same level as models.py, views.py, etc. If this doesn’t already exist, create it - don’t forget the init.py file to ensure the directory is treated as a Python package.
The error tells you exactly what is wrong: you did not load the tag in the template where you are using it, ie index.html.
{% load loansTable %}
{% show_loans %}
Also, you are confusing your tag types. The tag that renders another template is called an inclusion tag, so you should use that when you register it:
#register.inclusion_tag('loansTable.html')
def show_loans():
...
I have recently installed Wagtail CMS, into an existing Django Project.
I have created a new App in my existing Django project, and placed the following into the models.py.
from __future__ import unicode_literals
from django.db import models
from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import FieldPanel
class HomePage(Page):
body = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('body', classname="full"),
]
If I visit the Wagtail CMS Admin, and then go to Explorer, and Add Child Page, I now see 'Home Page' as a new Page option. As desired.
However I have two problems: -
Firstly, only the title field is editable. The body field is not clickable.
Secondly when I publish the new page I get a template error: -
TemplateDoesNotExist at /pages/test/
blog/home_page.html
I have checked the documentation here:
http://docs.wagtail.io/en/v1.9/getting_started/tutorial.html
and it states the following:
The page template now needs to be updated to reflect the changes made
to the model. Wagtail uses normal Django templates to render each page
type. By default, it will look for a template filename formed from the
app and model name, separating capital letters with underscores (e.g.
HomePage within the ‘home’ app becomes home/home_page.html). This
template file can exist in any location recognised by Django’s
template rules; conventionally it is placed under a templates folder
within the app.
I created a home_page.html file in the blog app I created, and placed the following code into it:
{% extends "base.html" %}
{% load wagtailcore_tags %}
{% block body_class %}template-homepage{% endblock %}
{% block content %}
{{ page.body|richtext }}
{% endblock %}
But I am still getting the same error.
Can you advise how I can resolve template error, and (if connected) why the body field is not editable.
Thanks.
I'm sorry to ask this again, but I tried several solutions from stack overflow and some tutorials and I couldn't create a custom template tag yet. All I get is ImportError: No module named test_tag when I try to start the server via python manage.py runserver.
I created a very basic template tag (found here: django templatetag?) like so:
My folder structure:
demo
manage.py
test
__init__.py
settings.py
urls.py
...
templatetags
__init__.py
test_tag.py
test_tag.py:
from django import template
register = template.Library()
#register.simple_tag
def test_tag(input):
if "foo" == input:
return "foo"
if "bar" == input:
return "bar"
if "baz" == input:
return "baz"
return ""
index.html:
{% load test_tag %}
<html>
<head>
...
</head>
<body>
{% cms_toolbar %}
{% foobarbaz "bar" %}
{% foobarbaz "elephant" %}
{% foobarbaz "foo" %}
</body>
</html>
and my settings.py:
INSTALLED_APPS = (
...
'test_tag',
...
)
Please let me know if you need further information from my settings.py and what I did wrong so I can't even start my server. (If I delete 'test_tag' from installed apps I can start the server but I get the error that test_tag is not known, of course).
Thanks
The templatetagsfolder should be within an application.
You project tree should look something like:
demo
manage.py
test
__init__.py
settings.py
urls.py
test_app
__init__.py
models.py
tests.py
views.py
templatetags
__init__.py
test_tag.py
Then, add test_app to INSTALLED_APPS, and remove test_tag from there.
i use the django's default admin for the admin site, and i create a app named "project"
Then in the project change form, i want to show and dynamic image, i plan to draw some charts using the google API, so i must put change the html form to add a in the html file as below:
So my question is that how can i modify the django's default templates for this page, i can not find the form in templates/ folder, is this page named "change_form"? "change_list"? or some other names. If so ,how do i only change the form for app "Project" since maybe i will create some other apps in the same level with "project"
You need a place for static files which is valid.
Then place an admin directory inside that static files directory.
Then add your addname as a directory like this:
Root
yourapp
static
admin
yourapp
file_to_overwrite
Find your Django files. Then go to:
contrib/admin/templates/admin
On OSX this would be:
/Library/Python/2.7/site-packages/django/contrib/admin/templates/admin
Copy the file you want to overwrite to yourapp directory like above.
EDIT:
If you want to change a single form for a single app:
For example:
Root
yourapp
static
admin
yourapp
modelname
change_form.html
Only the model "modelname" will be affected by this html-file.
A good way to do this as the docs suggests is go with #Rickard Zachrisson answer but instead of copying it use the "extends" block and import super.
this should be a better approach since you are not directly overriding the admin templates but instead inheriting them.
This is how the docs suggests to do it when inserting JS for example:
{% extends 'admin/change_form.html' %}
{% load static %}
{% block admin_change_form_document_ready %}
{{ block.super }}
<script type="text/javascript" src="{% static 'app/formset_handlers.js' %}"></script>
{% endblock %}