Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: using objects.values() and get ForeignKey data in template

Tags:

django

I have a Django app where my main Model has ForeignKey fields to other DB tables.

class Bugs(models.Model):     bug_id = models.PositiveIntegerField(primary_key=True)     bug_severity = models.ForeignKey(Bug_severity,null=True)     priority = models.ForeignKey(Priority,null=True)     bug_status = models.ForeignKey(Bug_Status,null=True)     resolution = models.ForeignKey(Resolution,null=True)     etc... 

All of the ForeignKey tables have a unicode function that returns the name that I want displayed in the template.

class Priority(models.Model):     value = models.CharField(max_length=64)     sortkey = models.PositiveSmallIntegerField()     isactive = models.NullBooleanField()     visibility_value_id = models.SmallIntegerField(null=True,blank=True)      def __unicode__(self):         return self.value 

In the view, I am running the query as:

    bugs = Bugs.objects.filter(active=True).order_by('priority__sortkey','bug_severity__sortke 

In the template, I can iterate through them, and display the ForeignKey value correctly.

{% for bug in bugs %}    <tr class="bugrow" >    <td>{{bug.bug_id}}</td>    <td>{{bug.priority}}</td>    <td>{{bug.bug_severity}}</td>    <td>{{bug.bug_status}}</td>    <td>{{bug.resolution}}</td> 

The problem I am having is that I need to manipulate the Bugs data before sending it to the template, so I use the values() method to return a dictionary. When I pass that dictionary to the template it does not show any fields that point to a ForeignKey.

I'm pretty sure that the reason is that the values only returns the actual database value, so it cannot follow the FK.

The question is, how can I manipulate the data sending it to the template, and still follow the ForeignKey?

like image 380
zoidberg Avatar asked Nov 28 '14 00:11

zoidberg


People also ask

What's the difference between Django OneToOneField and ForeignKey?

A one-to-one relationship. Conceptually, this is similar to a ForeignKey with unique=True , but the "reverse" side of the relation will directly return a single object. In contrast to the OneToOneField "reverse" relation, a ForeignKey "reverse" relation returns a QuerySet .

What does .values do in Django?

values() Returns a QuerySet that returns dictionaries, rather than model instances, when used as an iterable. Each of those dictionaries represents an object, with the keys corresponding to the attribute names of model objects.

How does ForeignKey work in Django?

Introduction to Django Foreign Key. A foreign key is a process through which the fields of one table can be used in another table flexibly. So, two different tables can be easily linked by means of the foreign key. This linking of the two tables can be easily achieved by means of foreign key processes.

What does .all do in Django?

Definition of the all() manager method: all() Returns a copy of the current QuerySet (or QuerySet subclass). This can be useful in situations where you might want to pass in either a model manager or a QuerySet and do further filtering on the result.


1 Answers

I use this method all of the time. You are correct. It only returns the values, so you have to use the "__" notation to get the value from the ForeignKey. For example:

# Get all of the bugs bugs = Bugs.objects.filter(     active=True, ).order_by(     'priority__sortkey',     'bug_severity__sortkey', ).values(     'bug_id',     'priority', # Only the pk (id) of the bug priority FK     'priority__value', # Equal to bug.priority.value     'bug_severity',     'bug_severity__some_value', # Equal to bug.priority.some_value ) 

Now, in your template, you do:

{% for bug in bugs %}     <tr class="bugrow">         <td>{{ bug.bug_id }}</td>         <td>{{ bug.priority }}</td>         <td>{{ bug.priority__value }}</td>         <td>{{ bug.bug_severity }}</td>         <td>{{ bug.bug_severity__some_value }}</td>     </tr> {% endfor %} 

This is covered in the QuerySet.values() documentation, near the bottom:

You can also refer to fields on related models with reverse relations through OneToOneField, ForeignKey and ManyToManyField attributes:

Blog.objects.values('name', 'entry__headline') [{'name': 'My blog', 'entry__headline': 'An entry'},  {'name': 'My blog', 'entry__headline': 'Another entry'}, ...] 
like image 98
Michael B Avatar answered Sep 21 '22 09:09

Michael B