Reputation: 457
I want to go from showing the latest 10 objects from one model to showing the latest 10 objects from that and another model, treating the objects differently depending on the model they come from.
I have gone from (abbreviated):
views.py
latest_ModelA = ModelA.objects.order_by('-pk')[:10]
context = {'latest_10': latest_10}
to:
views.py
latest_ModelA = ModelA.objects.order_by('-pk')[:10]
latest_ModelB = ModelB.objects.order_by('-pk')[:10]
latest_combined = list(chain(latest_ModelA, latest_ModelB))
latest_combined.sort(key=lambda x: x.id, reverse=True)
context = {'latest_combined': latest_combined[:10]}
But how do I then go from:
index.html
{% for a in latest_ModelA %}
<a href="/display/thingA/{{ a.id }}/">{{ a.name }}</a>
{% endfor %}
to something like:
{% for a in latest_combined %}
{% if a.get_classname == "thingA" %}
<a href="/display/thingA/{{ a.id }}/">{{ a.name }}</a>
{% if a.get_classname == "thingB" %}
<a href="/display/thingB/{{ a.id }}/">{{ a.name }}</a>
{% endif %}
{% endfor %}
This feels wrong. Before I go deeper down this hole, can anyone propose a more elegant solution?
For reference:
models.py
class ModelA(models.Model):
(...)
class ModelB(models.Model):
a = models.ManyToManyField(ModelA)
Upvotes: 0
Views: 49
Reputation: 37319
Is the only difference in your desired rendering the URL? If so, I'd write a get_absolute_url
method for both model classes - this is exactly the kind of situation the example there discusses.
In general, you want behavior that varies by class to be defined by the class, not by inspecting the class type in the template.
Upvotes: 3
Reputation: 55962
You could put the method to generate the url on the model that way each instance/class will know how to build its own url without needing a conditional
class ModelA(models.Model):
def get_special_link(self):
return "/display/thingA/{}/".format(self.id)
class ModelB(models.Model):
def get_special_link(self):
return "/display/thingB/{}/".format(self.id)
or better yet use reverse
Upvotes: 1