I am thinking whether having url
tag that returns nothing when it cannot match any patterns wouldn’t be better choice than one that raises exception and prevents user from doing anything on page where this occurred?
This just happened to me yesterday, where I forgot to put one thing into the template context and it caused url
tag to give me a couple of 500s in production
I totally get that is MY problem and I should have been more careful and have better test coverage… Still if there were something like safeurl
tag as an alternative, I would be probably using it all the time. If it couldn’t match anything, then the href
would be empty - it wouldn’t work but the rest of the page would be more useful than having 500.
It could be paired with some sort of logging, so I would see in Sentry for example that there is invalid URL pattern being requested, but it wouldn’t bring down entire page.
Thougths?
This seems potentially very dangerous to me. (Think about targets for AJAX requests, or page redirects, or form submissions, etc.)
In the general case, you could create your own safeurl
tag in a custom tag library that calls the reverse
function and either returns the appropriate URL or an empty string.
(Edit: Adam’s answer provides the better explanation.)
1 Like
(Edit: Ken beat me, but we both think this is dangerous)
Django’s template language has copied some of the “ignore errors and just keep going” philosophy of PHP already, where missing variables don’t cause templates to crash.
In general I don’t think this is a good idea. Ignoring errors can lead to bigger errors, including security problems.
For example, in your case, writing <form action="{% safeurl ... %}">
which crashed and turned into <form action="">
, form data could be posted to the wrong destination.
A better defense is more testing.
Of course you’re free to implement your own safeurl
tag that does try/except
but I would be against adding this to the framework or encouraging its use.
1 Like
Thanks both! Turns out there are good reasons for the current behavior.