-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resolve #427: Don't display empty resources table for locations #477
Conversation
context['has_relationships'] = (num_relationships > 0) | ||
context['has_resources'] = len(spatial_unit.resources) > 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_context_data
needs some improvement.
First, the database is hit twice when getting the relationship and then getting the number of relationships. context['relationships']
is a QuerySet so you can call exists()
to find out if one record matches the filter. This is better written as:
context['relationships'] = TenureRelationship.objects.filter(
spatial_unit=spatial_unit)
context['has_relationships'] = context['relationships'].exists()
Second, spatial_unit.resources
is a QuerySet as well. Again, exists()
is the better choice.
context['has_resources'] = spatial_unit.resources.exists()
I'm not sure if has_resources
and has_relationships
is necessary. In the template you can write {% if relationships %}
or {% if location.resources %}
as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{% if relationships %}
will not work because relationships
refers to the spatial relationships of the location. I think {% if tenurerelationship_set %}
should work.
I'll try that as well as the {% if location.resources %}
. I'll update as needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a template {% if relationships %}
refers to what is in context['relationships']
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to clarify, I was thinking of also removing context['relationships']
and go straight to {% if location.tenurerelationship_set.all %}
. If context['relationships']
is removed, then {% if location.relationships %}
would now refer to the spatial relationships.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tried using {% if location.tenurerelationship_set.all %}
and {% if location.resources %}
in the template, and completely deleting get_context_data()
from the view. This worked.
@ian-ross, I'd like to understand the tidying you did. Am I correct that both approaches are functionally the same and both hit the Tenure Relationships DB table only once, but the tidy approach avoids putting model logic into the view logic? |
@seav Actually, your approach does hit the database twice. Every time you get a related QuerySet in a template (e.g. Ian's approach, on the other hand, caches the result and uses the same QuerySet in the template. You can read about it the Django docs. |
@seav As Oliver says, your approach does two queries. More importantly though, my approach makes it explicit that the intent is for a single query to be performed and the same results to be used for both occurrences of Not having model logic in the template is an additional benefit of assigning the queryset results to an explicit name in the context data. I'm still working out the best way to do these things in Django, but I think that explicit names for shared results and avoiding complex logic in templates are two good principles to start with. |
No description provided.