Code

Opened 20 months ago

Closed 3 months ago

#18942 closed Cleanup/optimization (fixed)

Documentation of `{% get_static_prefix %}` unclear

Reported by: aaugustin Owned by: nobody
Component: Documentation Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The documentation says:

If you’re not using RequestContext, or if you need more control over exactly where and how STATIC_URL is injected into the template, you can use the get_static_prefix template tag instead:


{% get_static_prefix %} was introduced in [33d8fcde8a]. It essentially returns iri_to_uri(settings.STATIC_URL).

The documentation implies that {% get_static_prefix %} is equivalent to {{ STATIC_URL }}. In theory it isn't, because the static context processor doesn't apply iri_to_uri, while the get_static_prefix tag does. I don't know if it matters in practice.

Furthermore, I don't understand how {% get_static_prefix %} gives me "more control".

I can see several ways to resolve this, the simplest would be:

  • also apply iri_to_uri in the static context processor (and in the media context processor) for consistency
  • simply state that {% get_static_prefix %} is an alternative to {{ STATIC_URL }} that doesn't require a context processor

There's also a built-in {% static %} tag, and another version provided by contrib.staticfiles since [1d32bdd3c9].

Having four different ways to achieve the same result — with various degrees of sophistication — is confusing. Is there a good reason to keep {% get_static_prefix %} and {{ STATIC_URL }}, if they do essentially the same thing? IOW is the ability not to use the static request context processor useful?

Attachments (0)

Change History (7)

comment:1 Changed 20 months ago by jezdez

This is mostly historical, {% static %} didn't exist at first (in 1.3) so get_static_prefix was an "easy" way to get the value of STATIC_URL.

comment:2 Changed 20 months ago by jezdez

Oh, I forgot to mention, each have different use cases:

  • {{ STATIC_URL }} only works if you have the request in the context
  • get_static_prefix does everywhere (both of them were in 1.3)
  • {% static %} from staticfiles uses the storage and was added later along the core {% static %} tag that just joins the given path with the STATIC_URL (in case anyone doesn't want to use the contrib app staticfiles)

IMO we should only recommend the core {% static %} tag or the staticfiles equivalent instead of {{ STATIC_URL }} as it always works. get_static_prefix should be deprecated in favor of that. The context processors should use iri_to_uri.

comment:3 Changed 20 months ago by jezdez

  • Component changed from Documentation to contrib.staticfiles
  • Triage Stage changed from Unreviewed to Accepted

comment:4 Changed 19 months ago by aptiko

The currently most usual way of referring to static files, settings.STATIC_URL + filename, breaks when STATIC_URL is an absolute URL (e.g. "http://my-static-files.com/"). The problem is that the static url, in that case, should be different depending on request.is_secure(); however, currently Django assumes a single value for STATIC_URL and this has to be hacked around (for example, I am about to use the nginx HttpSubModule functionality to replace URLs in the response body).

Using the {% static %} and friends may be a solution to this problem, however there are some issues:

  1. Currently the documentation only explains how to use that functionality in templates; it doesn't say what to do in Django code.
  2. The documentation describes this functionality as an edge case, i.e. using a CDN, and implies that the old way of using STATIC_URL is otherwise OK. This means that if you have a well-written application that uses the common practice of STATIC_URL, and you need to put it to work with a CDN, it is necessary to rewrite some application code, whereas it should only be needed to change settings (and maybe provide a CDN driver).

In other words, all that static stuff needs rethinking, or maybe just deprecating the old methods in favour of {% static %} et al.

Needless to say, all this applies to media files as well.

comment:5 Changed 19 months ago by aaugustin

Serving a website with the same settings on HTTP and HTTPS isn't a problem for static files, just use a protocol-relative STATIC_URL eg. '//my-static-files.com/'. (It may be a bad idea for other reasons, for instance you're sharing the session cookie between HTTP and HTTPS, which isn't great for security.)

I'm going to be blunt -- saying that "all that static stuff needs rethinking" doesn't help, besides pissing of the (smart) people who put a lot of time and effort into implementing it. If you believe that "all this applies to media files as well", quite obviously, you haven't understood the goals and the use case of the staticfiles application.

You're welcome to contribute on this topic, but please take the time to study and understand the existing features before dismissing them, and take into account backwards-compatibility and history.


So let's keep this ticket on topic. It's specifically about recommending {% static %} in the docs, explaining why {% get_static_prefix %} exists, and (maybe) deprecating it. Actually there isn't a lot of value in this deprecation; we could just leave it for people who happily use it, but discourage its use in the documentation.

comment:6 Changed 11 months ago by timo

  • Component changed from contrib.staticfiles to Documentation

comment:7 Changed 3 months ago by Tim Graham <timograham@…>

  • Resolution set to fixed
  • Status changed from new to closed

In 85149a8b7fb560960fb6e8b64e1d9f486e982c19:

[1.6.x] Fixed #18942 -- Clarified usage of {% get_static_prefix %}.

Thanks Aymeric for the suggestion.

Backport of bc7668eb51 from master

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.