[Fixed]-Append additional values to queryset in Django generic views before handing to template

1👍

You should overload the get_queryset method of the ListView like so

def get_queryset(self, **kwargs):
    queryset = super(AppointmentListView, self).get_queryset(**kwargs)
    # Add new elements here
    ...
    return queryset

0👍

I got this working by overriding get_queryset() and giving the objects (i.e. each row in the db) an extra on-the-fly key/value:

class AppointmentListView(LoginRequiredMixin,ListView):
    #friendly template context
    context_object_name = 'appointments'
    template_name = 'appointments/appointment_list.html'

    def get_queryset(self):
        qs = Appointment.objects.prefetch_related('client','patients')
        for r in qs:
            if r.status == r.STATUS_UPCOMING: r.css_button_class = 'default'
            if r.status == r.STATUS_ARRIVED: r.css_button_class = 'warning'
            if r.status == r.STATUS_IN_CONSULT: r.css_button_class = 'success'
            if r.status == r.STATUS_WAITING_TO_PAY: r.css_button_class = 'danger'
            if r.status == r.STATUS_PAYMENT_COMPLETE: r.css_button_class = 'info'
        return list(qs)

A couple of things:

  1. I converted the queryset qs to a list to ‘freeze’ it. This prevents the queryset from being re-evaluated (e.g. slice) which, in turn, would cause the on-the-fly model changes to be lost as fresh data is pulled from DB.

  2. I needed to assign a value to template_name explicitly. When overriding get_queryset the template name is not derived automagically. As a comparison, the code below whose queryset attribute is set, generates the template name automatically:

    class AppointmentListView(LoginRequiredMixin, ListView):
        queryset = Appointment.objects.prefetch_related('client', 'patients')
        #template name FOO_list derived automatically
    
    #appointments/views.py
    ...
    #can use derived name (FOO_list)
    {% for appointment in appointment_list %}
    ...
    

Leave a comment