iShaymus
iShaymus

Reputation: 532

Django - Cannot get model to display in template

I'm creating an availability app for Volunteer Firefighters and cannot get one of the model fields to display in the template:

models.py

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models

# Create your models here.
class Team(models.Model):
  name = models.CharField('Name', max_length = 200)

  def __str__(self):
    return self.name

class Firefighter(models.Model):
  RANKS = (
    ('CFO', 'Chief Fire Officer'),
    ('DCFO','Deputy Chief Fire Officer'),
    ('SSO', 'Senior Station Officer'),
    ('SO', 'Station Officer'),
    ('SFF', 'Senior Firefighter'),
    ('QFF', 'Qualified Firefighter'),
    ('FF', 'Firefighter'),
    ('RFF', 'Recruit Firefighter'),
    ('OS', 'Operational Support'),
  )

  STATUS_OPTIONS = (
    ('AV', 'Available'),
    ('OD', 'On Duty'),
    ('UN', 'Unavailable'),
    ('LV', 'Leave'),
  )
  
  rank = models.CharField("Rank", max_length = 50 , choices=RANKS, default='RFF')
  first_name = models.CharField("First Name", max_length = 200)
  last_name = models.CharField("Last Name", max_length = 200)
  start_date = models.DateField(name="Start Date")
  status = models.CharField("Status", max_length = 20 , choices=STATUS_OPTIONS, default='Available')
  driver = models.BooleanField('Driver', default=False)
  officer = models.BooleanField('Officer Qualified', default=False)
  teams = models.ManyToManyField(Team)

  def __str__(self):
   return self.first_name + ' ' + self.last_name

  class Meta:
        verbose_name = "Firefighter"
        verbose_name_plural = "Firefighters"

views.py

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.shortcuts import render
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from django.forms import ModelForm
from .models import Firefighter
from django.http import HttpResponseRedirect

# Create your views here.
@login_required(login_url='/login/')
def status(request):

  firefighters = Firefighter.objects.all()

  context = {
    'firefighters': firefighters,
    'availableCount': firefighters.filter(status='AV').count() + firefighters.filter(status='OD').count(),
    'leaveCount': firefighters.filter(status='LV').count(),
    'unAvCount': firefighters.filter(status='UN').count()
  }
  
  return render(request, 'status.html', context)

@login_required(login_url='/login/')
def details(request, id):
  class ChangeStatus(ModelForm):
    class Meta:
      model = Firefighter
      fields = ['status']
  
  form = ChangeStatus()
  firefighter = Firefighter.objects.get(id=id)

  if request.method == 'POST':
    form = ChangeStatus(request.POST, instance=firefighter)
    if form.is_valid():
      form.save() 
      return HttpResponseRedirect('/status/')
  else:
    form = ChangeStatus()

  context = {
    'firefighter': firefighter,
    'form': form
  }
  
  return render(request, 'details.html', context)

def members(request):

  firefighters = Firefighter.objects.all().order_by('rank')

  context = {
    'firefighters': firefighters,
  }
  return render(request, 'members.html', context)

and the members.html that won't render correctly:

{% extends "base.html" %}

{% block content %}
  <ul>
    {% for firefighter in firefighters %}
      <li> {{firefighter.rank}} {{firefighter.first_name}} {{firefighter.last_name}} {{firefighter.start_date}}</li>
    {% endfor %}
  </ul>
{% endblock content %}

The members.html will correctly render firefighter.first_name and firefighter.last_name but nothing displays for firefighter.start_date even though each firefighter has a specified start date in the database.

Any ideas as to why?

Bonus question: Is there any way for me to sort the ranks as they are listed in the model when querying the database?

Upvotes: 2

Views: 428

Answers (2)

Carl Brubaker
Carl Brubaker

Reputation: 1665

As far as your ordering, try setting variables for your choices with a value that will sort.

CFO = ‘A’
DCFO = ‘B’
...

RANK_CHOICES = (
    (CFO, ‘Chief Fire Officer’),
    (DCFO, ‘Deputy Chief Fire Officer’)
    (...)
    )

If you always wanted query results by rank:

class Meta:
    ordering = [‘rank’]

If not, use the current query you have.

As mentioned in Zev’s answer “name=‘label’” is not valid for any field. It is verbose_name=‘label. Depending on the field you can put the label as the first argument in quotes, but other fields you have to use verbose_name.

Upvotes: 1

Zev
Zev

Reputation: 3491

Where you define the field for the start_date you have:

start_date = models.DateField(name="Start Date")

It should be:

start_date = models.DateField("Start Date")

The first arg in Date_Field is verbose_name which will automatically set the name with a more acceptable snake_case version of the name.

Upvotes: 1

Related Questions