Reputation: 1061
I'm looking for a way to dynamically add extra attributes to django model instances so that they are accessible in the template
For example,
in models.py
class Foo(models.Model):
name = models.TextField()
in views.py
def my_view(request):
f = Foo.objects.get(id=1234)
# method in question
f.____add_extra_attribute____('extra_attribute', attr_value)
return render(request, 'my_template.html', {'foo_instance':f})
in my_template.html
<h1>{{ foo_instance.name }}</h1>
<p>{{ foo_instance.extra_attribute }}</p>
is there a way to accomplish this without rendering the instance as a dictionary instead of a Foo model object?
Upvotes: 4
Views: 9812
Reputation: 6503
Look at the example below. This is real code from my project. Here I have attached an attribute to the model object itself.
My model:
class Task(models.Model):
name = models.CharField(max_length=500)
description = models.TextField(max_length=500, blank=True)
assignee = models.ForeignKey(Employee, on_delete=models.CASCADE)
project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
report = models.ForeignKey(UtilizationReport, on_delete=models.CASCADE, null=True)
role = models.ForeignKey(Role, on_delete=models.CASCADE, null=True, blank=True)
billable_efforts = models.FloatField(
validators=[MinValueValidator(0.0), MaxValueValidator(1.0)],
)
created_at = models.DateTimeField(default=timezone.now, editable=False)
reviewed = models.BooleanField(default=False)
In view.py:
task = Task.objects.get(id=1) # Just an example...won't be really using get with id
task_rate = BillingCatagoryRate.objects.get(rate_card=invoice.rate_card, billing_category=task.assignee.billing_category).billing_rate
task.task_price = task_rate * task.billable_efforts # Note: task_price is NOT a model field.
In the template:
<td class="text-center">{{ task.task_price }}</td>
Upvotes: 0
Reputation: 473813
Following @mgilson's comment, you can pass the extra_attribute
to the template in a separate context variable:
def my_view(request):
f = Foo.objects.get(id=1234)
extra_attribute = attr_value
return render(request, 'my_template.html',
{'foo_instance': f, 'extra_attribute': attr_value})
If you still want to set the attribute on a model instance, you can set it directly:
f.extra_attribute = attr_value
Upvotes: 4