Opened 4 years ago

Closed 2 years ago

#15102 closed New feature (wontfix)

find_template returns compiled Template object instead of template source

Reported by: vmanchev Owned by: vmanchev
Component: Template system Version: 1.3
Severity: Normal Keywords: find_template template source
Cc: Kronuz Triage Stage: Design decision needed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

It seems that after introducing the new template loaders find_template method returns Template object instead of template source.

Has anyone noticed that behaviour? Is it intended and if so how to get template source?

Attachments (1)

django.template.loader.patch (636 bytes) - added by vmanchev 4 years ago.
Template loader patch

Download all attachments as: .zip

Change History (12)

Changed 4 years ago by vmanchev

Template loader patch

comment:1 Changed 4 years ago by vmanchev

  • Has patch set
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Adding a patch which fixes the issue for me, it adds a load_source parameter to find_template and Loader call methods with a reasonable default.

comment:2 Changed 4 years ago by vmanchev

  • Owner changed from nobody to vmanchev
  • Status changed from new to assigned

comment:3 Changed 4 years ago by ramiro

  • Triage Stage changed from Unreviewed to Design decision needed

Before r11862 there was no find_template function or method and the find_template_source function entered a deprecation path so there was no unintended backward incompatible change but a explicit decision to not provide a way to access to the source code of the template.

There may be a case for a reviving an API to be able to do that. But would it be better to introduce it as a parallel API? (maybe reintroducing find_template_source?) instead of modifying the find_template signature?

comment:4 follow-up: Changed 4 years ago by vmanchev

Replying to ramiro:

Before r11862 there was no find_template function or method and the find_template_source function entered a deprecation path so there was no unintended backward incompatible change but a explicit decision to not provide a way to access to the source code of the template.

I'm not sure why this decision was taken and why these methods were/are still in code in this case? Probably security concerns?
Indeed, I don't really need find_template_source, we're using find_template which returns template source if using django.template.loaders.app_directories.load_template_source and django.template.loaders.filesystem.load_template_source as TEMPLATE_LOADERS.

I noticed the problem when migrating part of our code base to Django 1.3 - I was getting deprecation warnings, wanted to get rid of them, so used new django.template.loaders.app_directories.Loader and django.template.loaders.filesystem.Loader as TEMPLATE_LOADERS.

There may be a case for a reviving an API to be able to do that. But would it be better to introduce it as a parallel API? (maybe reintroducing find_template_source?) instead of modifying the find_template signature?

Anyway, I think this is a case for reviving an API - we're using this particular functionality in a home grown CMS and we prefer to continue using this even with future versions of Django.

comment:5 in reply to: ↑ 4 ; follow-up: Changed 4 years ago by ramiro

Just to be clear (because I realise I wasn't): I meant find_template_source function entered a deprecation path in from that commit (r11862) and 1.2 (the release that followed it).

Replying to vmanchev:

Replying to ramiro:

Before r11862 there was no find_template function or method and the find_template_source function entered a deprecation path so there was no unintended backward incompatible change but a explicit decision to not provide a way to access to the source code of the template.

I'm not sure why this decision was taken and why these methods were/are still in code in this case?

Because that's how the deprecation policy works. A feature is removed after three releases. but use of that feature prints gradually noisier warnings (the ones you are seeing).

Indeed, I don't really need find_template_source, we're using find_template which returns template source if using django.template.loaders.app_directories.load_template_source and django.template.loaders.filesystem.load_template_source as TEMPLATE_LOADERS.

This is the part I don't understand, you say you were using TEMPLATE_LOADERS = ['django.template.loaders.app_directories.load_template_source'', ' django.template.loaders.filesystem.load_template_source'] and that indicates Django 1.1 or older (becase class based template loaders didn't exist then) but you also say you were using find_template() that didn't exist until 1.2. It's not clear to me what Django version are you porting your project from.

Related to this: We forgot to add a note about the new class based loaders to the 1.2 release notes, that is ticket #14038.

comment:6 in reply to: ↑ 5 Changed 4 years ago by vmanchev

Replying to ramiro:

Just to be clear (because I realise I wasn't): I meant find_template_source function entered a deprecation path in from that commit (r11862) and 1.2 (the release that followed it).

Replying to vmanchev:

Replying to ramiro:

Before r11862 there was no find_template function or method and the find_template_source function entered a deprecation path so there was no unintended backward incompatible change but a explicit decision to not provide a way to access to the source code of the template.

I'm not sure why this decision was taken and why these methods were/are still in code in this case?

Because that's how the deprecation policy works. A feature is removed after three releases. but use of that feature prints gradually noisier warnings (the ones you are seeing).

Yes, I understand this - that's why I want to get on the right track by resolving these deprecation warnings.

Indeed, I don't really need find_template_source, we're using find_template which returns template source if using django.template.loaders.app_directories.load_template_source and django.template.loaders.filesystem.load_template_source as TEMPLATE_LOADERS.

This is the part I don't understand, you say you were using TEMPLATE_LOADERS = ['django.template.loaders.app_directories.load_template_source'', ' django.template.loaders.filesystem.load_template_source'] and that indicates Django 1.1 or older (becase class based template loaders didn't exist then) but you also say you were using find_template() that didn't exist until 1.2. It's not clear to me what Django version are you porting your project from.

Related to this: We forgot to add a note about the new class based loaders to the 1.2 release notes, that is ticket #14038.

Well, obviously the reason why we were using the old template loaders is that the documentation has not been updated and that passed unnoticed. Therefore, project is being ported from Django 1.2 to Django 1.3.

comment:7 Changed 4 years ago by adamnfish

  • Severity set to Normal
  • Type set to Uncategorized
  • Version changed from 1.2 to 1.3

The problem with dropping support for fetching just the template's source is that it makes it much harder to integrate another template language into projects. If find_template_source exists, we can use it to fetch templates in a way that is well documented without having to resort to additional settings or duplication of Django's code. The key is that developers should be able to specify the correct Loaders and customise their template locations in a template-agnostic fashion.

For developers who created their projects prior to v1.2, the auto-generated TEMPLATE_LOADERS setting has always pointed at the old (now deprecated) loader and only now, having upgraded to Django 1.3 are they a) seeing loud deprecation warnings and b) finding that these warnings cannot easily be worked around!

The new implementation couples the Loader classes to Django's Template object in line 48 of loader.py (1.3 tag) template = get_template_from_string(source, origin, template_name). This is a real shame, because Django has cleverly fetched the source and template_name which is exactly what is needed to integrate another template language!

I agree that altering find_template's signature doesn't feel like the correct approach - ideally find_template_source will make a re-appearance. It could use the load_template_source method of each Loader defined in the settings to fetch the actual source without creating a Django Template object.

I also think that the variables should be renamed to properly reflect whether they refer to the source (a string or string-like-object representing the template's source code) or a template instance (a Django template object with a render method). This is a very important distinction but it is very hard to tell the difference for a given location by looking at Django's source code. (one has to follow the variable all the way up the call chain to check if get_template_from_string has already been called on it!)

Let me know if this sounds sensible and I can look into implementing these changes.

comment:8 Changed 4 years ago by jaddison

  • Type changed from Uncategorized to New feature

This feels like a change to a) documentation and/or b) actual functionality. As such, I'm marking it as a New Feature.

comment:9 Changed 4 years ago by aaugustin

  • Easy pickings unset

#15948 was a duplicate.

comment:10 Changed 4 years ago by Kronuz

  • Cc Kronuz added
  • UI/UX unset

comment:11 Changed 2 years ago by jacob

  • Resolution set to wontfix
  • Status changed from assigned to closed

I don't buy the argument that missing find_template_source makes it hard to integrate other template languages -- people (including me) have been doing it since this change went in, and it's not particularly hard. Accordingly, I'm going to make the call that this isn't really needed.

Note: See TracTickets for help on using tickets.
Back to Top