17đź‘Ť
Use the with tag:
{% for physician in physicians.all %}
{% if physician.service_patients.count %}
{% with physician.service_patients as patients %}
<div id="tabs-{{ forloop.counter }}">
{% include "hospitalists/patient_list.html" %}
</div>
{% endwith %}
{% endif %}
{% endfor %}
You might also upgrade to creating a custom tag:
{% for physician in physicians.all %}
{% if physician.service_patients.count %}
{% patient-list physician.service_patients %}
{% endif %}
{% endfor %}
Although custom tags involve writing Python code, there are shortcuts that make it easy to use an existing template file as a tag: Django Inclusion Tags
3đź‘Ť
When you have “functionality” (specifically an if-condition) inside a loop, you have an opportunity to move this into the view function.
First
This construct
{% for physician in physicians.all %}
{% if physician.service_patients.count %}
{% endif %}
{% endfor %}
Is so common that you have several ways to avoid it.
-
Change your model. Add a
patients" method and use it instead of the default query set that you get with a on-to-many relationship. This method of your model has the
if service_patients.count` test, removing it from your template.This eliminates the {% if %} from your template, reducing it to {% for %} and the actual HTML, which cannot easily the eliminated.
-
Change your view function. Write a few lines of code to create a list of physicians with service_patients instead of a simplistic collection of physicians. This code in your view function has the
if service_patients.count
test, removing it from your template.This eliminates the {% if %} from your template, reducing it to a {% for %} and the actual HTML, which cannot easily be eliminated.
The point is to get rid of the {% if %} so that you’re simply cutting and pasting the {% for %} and the actual HTML. By keeping your template to just the HTML (which cannot be eliminated), the only overhead is the {% for %}
Second
It appears that you want to reuse an {% include %}
construct in slightly different contexts.
It’s not at all clear what the problem with this {% include %}
file is. It is “expecting a list of patients named patients
” seems superficially silly. Fix it, so it expects physician.patients
.
Perhaps you want to use this same list twice. Once with a list called 'patients'
and once with a list called 'physician.patients'
. In this case, consider (a) simplifying or (b) writing a template tag.
It appears that you have a patient list that is sometimes a stand-alone page, and other times is repeated many times on a much more complex page. Repeating a list of details embedded in some longer list is not really the best page design. Django doesn’t help you with this because — frankly — it’s not easy for people to use. Hence option (a) — consider redesigning this “patient list within a physician” list as too complex.
However, you can always write a template tags to create really complex pages.
Summary
There’s a really good reason why the Django template language has limited functionality. All of your functionality should be either an essential feature of your model, or a feature of the current application that uses the model.
Presentation is simply the translation of objects (and querysets) into HTML. Nothing more
- Django: Giving validation error feedback on a form after a post redirect get
- Editing response content in Django middleware
1đź‘Ť
As way, you can try to use in quality templating language jinja. It is more flexible.
- Embed editable Google Doc Spreadsheet in web page
- Django-allauth: Only allow users from a specific google apps domain
- Django REST Framework different depth for POST/PUT?
- Django : HTML form action directing to view (or url?) with 2 arguments