Opened 9 years ago
Last modified 2 years ago
#25600 new Bug
Template `if` tag behavior change with 1.8, OneToOneField, RelatedObjectDoesNotExist is True?
Reported by: | Denis Cornehl | Owned by: | nobody |
---|---|---|---|
Component: | Template system | Version: | 1.8 |
Severity: | Normal | Keywords: | |
Cc: | felisiak.mariusz@… | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
We discovered a strange behavior change when upgrading from Django 1.7 to 1.8.
Let's assume we have a OneToOneField
like here:
class Customer(models.Model): name = models.CharField(max_length=100) class Project(models.Model): customer = models.OneToOneField(Customer) title = models.CharField(max_length=100)
the template gets the Customer
instance, without a project, in the context.
{% if customer.project %} {# on 1.8 we get here #} {% else %} {# on 1.7 we get here #} {% endif %}
when debugging and trying to access customer.project
in a django shell, we get a RelatedObjectDoesNotExist
in both versions, so this does not seem to have changed.
So to us it looks like the behavior of the if
tag in templates changed.
I'm happy to provide more info as needed, or test stuff. Or even write a PR / Fix if someone points me to possible places where this could have been changed / broken.
Change History (7)
comment:1 by , 9 years ago
comment:2 by , 9 years ago
wanted to play around a little to find the point where it stopped working (in our codebase).
I starts happening when we set TEMPLATE_STRING_IF_INVALID
to any value (with %s
or without)
Out of curiosity I tried if it's related to the old (TEMPLATE_STRING_IF_INVALID
or the new (string_if_invalid
option in the TEMPLATES
config, but it happens always.
comment:4 by , 9 years ago
Severity: | Normal → Release blocker |
---|---|
Triage Stage: | Unreviewed → Accepted |
Okay, making that setting a non-empty value is the piece I was missing to reproduce. Bisected the change to 0dd05c9e66ebb5cb97136f84373f43582783e1a6. It's not immediately obvious to me what the resolution should be, but at least some documentation could be added if we decide not to change the behavior.
comment:5 by , 9 years ago
The RelatedObjectDoesNotExist
exception is a subclass of AttributeError
-- that's why it's hitting that logic added in the commit noted in the previous comment. We end up checking {% if <string_if_invalid> %}
which passes for a non-empty string_if_invalid
. I'm not sure we should add special handling of RelatedObjectDoesNotExist
in the template engine to restore the old behavior (and I'm not sure how to since RelatedObjectDoesNotExist
is a dynamically generated exception based on the related descriptors).
I think the usage of string_if_invalid
is somewhat unreliable/unpredictable anyway and therefore discouraged but I'm not too sure as I haven't used it myself.
comment:6 by , 9 years ago
Cc: | added |
---|
comment:7 by , 9 years ago
Severity: | Release blocker → Normal |
---|
Per discussion on django-developers, demoting from a release blocker since string_if_invalid
is only intended for debugging. Inconsistencies in how the {% if %}
tag silences exceptions (#17664) may be related.
I can't reproduce that -- I'm always seeing the else branch on master and stable/1.8.x. Maybe you could provide a failing test case for Django's test suite?