Unresolved tag in PyCharm - django

I have this issue of pycharm showing me unresolved tag after i successfully loaded the file containing the custom tag. Please someone help!!
this is the content of my carton-tags.py file containing custom template tags
from django import template
from carton.cart import Cart
from carton.settings import CART_TEMPLATE_TAG_NAME
register = template.Library()
#register.filter
def get_cart(context, session_key=None, cart_class=Cart):
"""
Make the cart object available in template.
Sample usage::
{% load carton_tags %}
{% get_cart as cart %}
{% for product in cart.products %}
{{ product }}
{% endfor %}
"""
request = context['request']
return cart_class(request.session, session_key=session_key)
register.assignment_tag(takes_context=True, name=CART_TEMPLATE_TAG_NAME)(get_cart)

You are using get_cart filter as a template tag in you template. This is why pycharm is showing errors.
#register.filter
def get_cart(context, session_key=None, cart_class=Cart):
You should remove register.filter decorator if you are not using it as a filter.

Related

get request context in Advanced custom template tags

In Django simple and inclusion template tags allow getting the request context with
#register.simple_tag(takes_context=True)
Official documentation for custom template tags - inclusion tags.
However, for custom tags, I don't see how this is done.
What I am trying to do is extend the i18n {% trans %} tag, to look for translation in the database first, before using gettext. I need access to the request.Language from the custom template tag.
From the Django doc of custom template tags, it's also possible to add takes_context for customs tags
import datetime
from django import template
register = template.Library()
#register.simple_tag(takes_context=True)
def current_time(context, format_string):
#use "context" variable here
return datetime.datetime.now().strftime(format_string)
I'm not sure how to override the existing tag at this particular scenario :( Anyway, what I'm suggesting is, create a simple_tag that takes the context and do your logic inside the tag and return the translation text from DB. If it's not in DB, return a boolean False. Now in template, check these thing using if tag.
from django import template
register = template.Library()
#register.simple_tag(takes_context=True)
def is_db_available(context):
# access your context here and do the DB check and return the translation text or 'False'
if translation_found_in_DB:
return "Some translation text"
return False
and in template
{% load custom_tags %}
{% load i18n %}
{% is_db_available as check %}
{% if check %} <!-- The if condition -->
{{ check }}
{% else %}
{% trans "This is the title." %} <!-- Calling default trans tag -->
{% endif %}

How to replace placeholders in placeholders (variables) in Django?

In a Django template, I'd like to add text from a model field. This text field can be understood as text-template itself. It may look like:
Dear {{user}},
thank your for...
Regards,
{{sender}}
This text field is available as emailtemplate inside a normal Django template. The fields from above (user=Joe, sender=Alice) are available as well.
{% extends 'base.html' %}
{% block content %}
{{ emailtemplate }}
{% endblock %}
The output shall be as follows
Dear Joe,
thank your for...
Regards,
Alice
I have no clue how to do this with built-in methods. My only idea is to parse emailtemplate manually before I hand it over to the template engine, thus inside the view. But I'm sure, I'm not the first one with that problem.
After several reworks, I came up with the following solution. Double check who can modify/alter the template string since this could be a big security flaw, if alterable by the wrong people.
views.py:
class YourView(TemplateView):
template_name = 'page.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["emailtemplate"] = "Dear {{user}}, {{sender}}"
context["user"] = "Joe"
context["sender"] = "Alice"
return context
page.html:
{% extends 'base.html' %}
{% load core_tags %}
{% block content %}
{% foobar emailtemplate %}
{% endblock %}
your_app/templatetags/core_tags.py (don't forget the __init__.py file to ensure the directory is treated as a Python package your_app must also be in INSTALLED_APPS):
from django import template
from django.template import Template
register = template.Library()
#register.simple_tag(takes_context=True)
def foobar(context, ts):
t = Template(template_string=ts)
return t.render(context)
See also:
https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/#code-layout
https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/#simple-tags

Where to import stuff for a template in Django?

Sorry for the dumb question, I'm lost.
I got a template and a templatetags with this :
menu_tags.py
from django import template
from menu.models import Button
register = template.Library()
#register.inclusion_tag('menu/home.html')
def show_menu():
buttons = Button.objects.all()
return {'buttons': buttons}
And this :
home.html
{% for button in buttons %}
{% if user.is_authenticated %}
stuff
{% endif %}
{% endfor %}
I would like to know, how can I make user.is_authenticated work ? I know I have to import something, but where ? Importing it in menu_tags does not seems to work.
Thanks !
As suggested by other users in the comments, try the following:
from django import template
from menu.models import Button
register = template.Library()
#register.inclusion_tag('menu/home.html', takes_context=True)
def show_menu():
request = context['request']
if request.user.is_authenticated: # if Django 1.10+
buttons = Button.objects.all()
else:
buttons = None
return {'buttons': buttons}
And then in your template, make sure you load your new templatetags and try:
{% load menu_tags %}
{% for button in buttons %}
{{ button }}
{% endfor %}

How to access an attribute of an object using a variable in django template?

How can I access an attribute of an object using a variable? I have something like this:
{% for inscrito in inscritos %}
{% for field in list_fields_inscrito %}
{{inscrito.field}} //here is the problem
{% endfor %}
{% endfor %}
For example Inscrito have: inscrito.id, inscrito.Name and inscrito.Adress and I only want to print inscrito.id and inscrito.Name because id and Name are in the list_fields_inscrito.
Does anybody know how do this?
You can write a template filter for that:
myapp/templatetags/myapp_tags.py
from django import template
register = template.Library()
#register.filter
def get_obj_attr(obj, attr):
return getattr(obj, attr)
Then in template you can use it like this:
{% load myapp_tags %}
{% for inscrito in inscritos %}
{% for field in list_fields_inscrito %}
{{ inscrito|get_obj_attr:field }}
{% endfor %}
{% endfor %}
You can read more about writing custom template tags.
Fixed answer for non string attributes
The selected answer don't cover cases where you need to access non string attributes.
If you are trying to access an attribute that isn't a string, then you must use this code:
from django import template
register = template.Library()
#register.filter
def get_obj_attr(obj, attr):
return obj[attr]
For this, create a folder named templatetags on your app's folder, then create a python file with whatever name you want and paste the code above
inside.
Inside your template load your brand new filter using the {% load YOUR_FILE_NAME %}, be sure to change YOUR_FILE_NAME to your actual file name.
Now, on your template you can access the object attribute by using the code bellow:
{{ PUT_THE_NAME_OF_YOUR_OBJECT_HERE|get_obj_attr:PUT_THE_ATTRIBUTE_YOU_WANT_TO_ACCESS_HERE }}

Django - How to retrieve an object from a custom template tag?

I'm without clues on solving this problem.
I've a template tag that receives an Object:
{% score_for_object OBJECT_HERE as score2 %}
The problem is that I'm passing to the template a context that came from a raw select:
cursor = connection.cursor()
cursor.execute("select ...")
comments = utils.dictfetchall(cursor)
To solve the problem of the template tag that accepts a Django object, I've write a template tag:
'''
This template tag is used to transform a comment_id in an object to use in the django-voting app
'''
def retrive_comment_object(comment_id):
from myapp.apps.comments.models import MPTTComment
return MPTTComment.objects.get(id=comment_id)
With this template tag I expected this to work:
{% for item in comments %}
{% score_for_object item.comment_id|retrieve_comment_object as score2 %}
{{ score2.score }} {# expected to work, but not working #}
{% endfor %}
My question. It is possible to retrieve an object from a template tag?
Best Regards,
To get the score:
from django import template
from myapp.apps.comments.models import MPTTComment
register = template.Library()
#register.simple_tag
def retrive_comment_object(comment_id):
data = MPTTComment.objects.get(id=comment_id)
return data.score
{% for item in comments %}
Score: {% retrive_comment_object item.comment_id %}
{% endfor %}