filter foreign keys in views.py

Date: March 20th 2016
Last updated: March 20th 2016

Filtering across foreign keys can be done in views.py. Something I didn't realise was that the context field can hold many objects, not just one. (The context field is the last argument in the return statement of a views method)

In this example, I was trying to create a page that would show diary entries for each surfer. I wanted to identify a surfer by their primary key. Then I wanted to filter the table containing diary entries to show only records for that surfer.

This example follows on from all other entries in this chapter. As such, only important code snippets are shown.

template: profile.html
profile.html has access to surfer.id which is a primary key. The user click's on "Diary". Note the removal of the href underline using text-decoration.

<div class="headermenu">
    <a href="{% url 'surferprofile:diary' surfer.id %}"
    style="text-decoration: none;">Diary</a>
</div>

urls.py
Clicking "diary" sends a request to urls.py and invokes the diary method in views.py.

app_name = 'surferprofile'
urlpatterns = [#<snipped>
    url(r'^(?P<surfer_id>[0-9]+)/diary/$',views.diary, name='diary'),
]

views.py
The diary method is in two parts. First, get the surfer profile information (get_object_or_404). Second filter another table (model), in this case SurfDiary, based on surfer.id. This is the primary key. Notice that the context field at the end of render is a dictionary containing two objects. Up until now I didn't realise I could load this up with information from multiple tables.

def diary(request, surfer_id):
    surfer = get_object_or_404(Surfer, pk=surfer_id)
    entry_list = SurfDiary.objects.filter(surfer = surfer.id)
    return render(request, 'surferprofile/diary.html',
                 {'surfer': surfer, 'surfdiary': entry_list})

template: diary.html
A request is sent and diary.html is rendered. I have used two objects in this example; first to render the surfers first name, and second to provide diary entries.

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
      <div>
          This is a diary entry for {{ surfer.firstname }}
      </div>
        {% if surfdiary %}
          <ul>
          {% for entry in surfdiary %}
              <li>
               <p> 
                  {{ entry.wavesize }}
                  {{ entry.winddir }}
                  {{ entry.board}}
              </p>
              </li>
          {% endfor %}
          </ul>
      {% else %}
          <p>No diary entries.</p>
      {% endif %}

  </body>
</html>

results matching ""

    No results matching ""