I'd like to figure out a way to use a key-value lookup for a second model within a Django for
loop.
This question on dictionary key-value loops in templates is on the right track, but I am using two normalized data models. There is a 'Parent' data object (EventDetail
) that contains the relevant link and 'Child' data object (DateEvent
) that has date-specific information with data on user actions.
I have a template tag, link_if_exists
, that is being duplicated many times. Django-debug-toolbar tells me this is being duplicated 76 times right now. This 'duplicate' message is, itself, duplicated many times.
This is what I have now:
app_extras.py
@register.filter()
def link_if_exists(title):
"""Return a link if it exists"""
event_link = None
try:
event_link = EventDetail.objects.filter(title=title).values_list('link', flat=True)[0]
except IndexError:
pass
if event_link != "":
return event_link
return False
template.html
{% load 'app_extras' %}
{% for item in child_date_items %}
{% if item.title|link_if_exists %}
<a href="{{item.title|link_if_exists}}">{{item.title}}</a>
{% endif %}
{% endfor %}
models.py
class DateEvent(models.Model)
title = models.CharField(max_length=250)
event_date = models.DateField(default=date.today)
event_datetime = models.DateTimeField(auto_now=False)
class EventDetail(models.Model)
title = models.CharField(max_length=250)
link = models.URLField(max_length=200, default="", blank=True)
views.py
class ProblemView(TemplateView):
template_name = "template.html"
def get_context_data(self, **kwargs):
context = super(ProblemView, self).get_context_data(**kwargs)
date_today = utils.get_date_today()
child_date_items = DateEvent.objects.filter(event_date=date_today)
context['child_date_items'] = child_date_items
return context
Django-debug-toolbar output
SELECT link FROM
table WHERE title='title'
...
| duplicated 74 times
Something like this is what I am after:
Add 'event_detail' to views.py
class NewView(TemplateView):
template_name = "template.html"
def get_context_data(self, **kwargs):
context = super(NewView, self).get_context_data(**kwargs)
date_today = utils.get_date_today()
child_date_items = DateEvent.objects.filter(event_date=date_today)
context['child_date_items'] = child_date_items
event_detail = EventDetail.objects.all()
context['event_detail'] = event_detail
return context
Lookup title as key to get 'link' value in ideal_template.html
{% for item in child_date_items %}
{% if event_detail[item.title]['link'] %}
<a href="event_detail[item.title]['link']">{{item.title}}</a>
{% endfor %}
{% endfor %}
I don't know if this functionality exists so I am open to other suggestions. I am also open to computing this in views.py
and iterating over a common object in the template. I understand that I could duplicate the link data and just add a link column in the DateEvent
model, but that seems wasteful and I'd like to avoid that if possible. This isn't the only field I need this type of logic, so adding everything to the Child object would take up a lot of extra space in the database.