Mihai Zamfir
Mihai Zamfir

Reputation: 2166

Django ListView - context not getting updated

views.py

class PaginatorView(_LanguageMixin, ListView):
    context_object_name = 'concepts'

    #some custom functions like _filter_by_first_letter   

    def get_queryset(self):
        # some logic here ...

        all_concepts = self._filter_by_letter(self.concepts, letters, startswith)
        #letters and startswith are obtained from the logic above

        print all_concepts
        return all_concepts

    def get_context_data(self, **kwargs):
        context = super(PaginatorView, self).get_context_data(**kwargs)
        print context[self.context_object_name]
        context.update({
            'letters': [(l[0], self._letter_exists(context[self.context_object_name], l)) for l in self.all_letters],
            'letter': self.letter_index,
            'get_params': self.request.GET.urlencode(),
        })

        return context

The print all_concepts statement prints all my concepts correctly. So everything until here works just fine. Then, I return all_concepts.

Shouldn't at this point, all_concepts being added to the context, under the key specified by context_object_name? i.e., context['concepts'] should be populated with all_concepts?

If so,the print statement inside get_context_data prints nothing. Which suggests me that the context was not updated.

When I previously used a DetailView, the get_object function was updating the context referenced by context_object_name correctly.(i.e. context[context_object_name] was populated with the object returned by get_object) Shouldn't get_queryset do the same for the ListView?

_LanguageMixin is also defined in views.py, but it is not so relevant for my problem. Just included it here for you to see

class _LanguageMixin(object):

    def dispatch(self, request, *args, **kwargs):
        self.langcode = kwargs.pop("langcode")
        self.language = get_object_or_404(Language, pk=self.langcode)
        return super(_LanguageMixin, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(_LanguageMixin, self).get_context_data(**kwargs)
        context.update({"language": self.language,
                        "languages": Language.objects.values_list('code',
                                                                  flat=True)})
        return context

[EDIT1]

if instead I do save all_concepts i.e. self.all_concepts=... and then I use self.all_concepts instead of context[self.contex_object_name], everything works fine.

[EDIT2]

I never instantiate the PaginatorView. It's only for extending purposes. Down here you can see how I extend it. self.concepts helps me to find all_concepts in the get_queryset of the parent class(PaginatorView)

class AlphabeticView(PaginatorView):
    template_name = "alphabetic_listings.html"
    model = Property

    def get_queryset(self):
        self.concepts = (
            self.model.objects.filter(
                name='prefLabel',
                language__code=self.langcode,
            )
            .extra(select={'name': 'value',
                           'id': 'concept_id'},
                   order_by=['name'])
            .values('id', 'name')
        )
        super(AlphabeticView, self).get_queryset()

Upvotes: 1

Views: 1776

Answers (1)

hellsgate
hellsgate

Reputation: 6005

The print statement in get_context_data is printing empty because the variable context_object_name is empty. You should try print context[self.context_object_name]

EDIT: In response to your correction, try

print context[self.get_context_object_name(self.get_queryset())]

get_context_object_name docs

EDIT 2: In response to your second edit, the reason its is printing 'None' is because you aren't returning from the get_queryset method of AlphabeticView. Change the last line in that method to

return super(AlphabeticView, self).get_queryset()

Upvotes: 1

Related Questions