I want to use abc.ABC abstract class objects (not an instance) in a Django template. In these classes, I have several class methods (defined with the @classmethod decorator) that I'd like to use for displaying informations.
When I try to show the list object: {{ dataset.provided_services }}
I get a list of class objects displayed:
[<class 'dataset_services.table_service.QueryTableService'>, <class 'dataset_services.table_service.ExportTableService'>]
But if I try to iterate over this list:
<ul>
{% for service in dataset.provided_services %}
<li>
<p>{{ service.name }}</p>
<p>{{ service.description }}</p>
</li>
{% endfor %}
</ul>
I get an error telling me that I cannot instantiate an abstract base class with abstract methods, as if django was trying to instantiate the class objects... Is this a normal behaviour? Is it possible to use class objects in a Django template without instantiating them?
PS: I'm using Django 1.8.5 and Python 3.4.
By default if the django template engine detects that a variable you are using is a callable it will call it before accessing sub-attributes. This is convenient in cases where you want the results of a function (which django doesn't allow you to explicitly call). If you'd rather not have a particular callable called in the django templates you can set the flag do_not_call_in_templates
to True
on your object. In your case you probably want to do this on your base class so every subclass has this attribute too.
TL;DR:
Set abc.ABC.do_not_call_in_templates = True
Full documentation on how the django template language treats variables and for more info on the do_not_call_in_templates flag
consult the django documentation.