Django 1.3, Python 2.7
I have the following models (some irrelevant fields omitted):
class Encounter(models.Model):
uuid = models.SlugField(max_length=36, unique=True, default=make_uuid, editable=False)
created = models.DateTimeField(auto_now_add=True)
subject = models.ForeignKey('Subject', to_field='uuid')
class Subject(models.Model):
given_name = models.CharField(max_length=64)
family_name = models.CharField(max_length=64)
system_id = models.CharField(max_length=32, blank=True)
uuid = models.SlugField(max_length=36, unique=True, default=make_uuid, editable=False)
def __unicode__(self):
return u'%s, %s - %s' % (self.family_name, self.given_name, self.system_id)
I would like to know which subjects appear in my encounters table and how many times they appear. The following code does what I want with one exception:
s_in_e = Encounter.objects.values('subject').annotate(mycount=Count('subject'))
When I attempt to display the results of my annotation as follows:
{% for thing in s_in_e %}
<p>{{ thing.subject }} was visited {{ thing.mycount }} time{{ thing.mycount|pluralize }}.</p>
{% endfor %}
It displays the subject's uuid
instead of the __unicode__()
. Research has shown that this is a property of values()
operating on a ForeignKeyField
- it only returns the id, not the object. Is there another way to calculate the number of times each subject appears in my encounters table so that I can at least display the __unicode__()
value? Ideally I would have access to the entire Subject object.
I am working on what is primarily someone else's code, so I cannot edit the existing structure of the models. I might be able to add a new field to the model if necessary.
You can start with Subject
and use the following code:
subjects = Subject.objects.prefetch_related('encounter_set')
And in your template:
{% for subject in subjects %}
<p> {{ subject }} was visited {{ subject.encounter_set.count }} time{{ subject.encounter_set.count|pluralize }}.</p>
{% endfor %}
prefetch_related
will get you all related encounters in a single additional query. subject.encounter_set
is a QuerySet
, so you can use the count()
method like on any other queryset.