django class based view 报错: 'get_context_data() keywords must be strings'

108 阅读1分钟

当我将django的list_object view重写为继承自django.views.generic.ListView的类视图时,在创建get_context_data方法时遇到了错误。

错误信息: 'get_context_data() keywords must be strings'

解决方案

经过仔细检查,我发现错误的原因是我在get_context_data方法中使用了kwargs参数,但其中一个键不是简单的字符串对象。具体来说,我使用了变量名作为键,但这些变量名是可延迟求值或可翻译的字符串。

为了解决这个问题,我将这些变量名替换为简单的字符串,错误消失了。

以下是我修改后的代码:

class ForumView(ListView):
    context_object_name = 'forum'
    template_name = 'forum/thread_list.html',
    paginate_by = FORUM_PAGINATION
    def get_queryset(self):
        try:
            f = Forum.objects.for_groups(self.request.user.groups.all()).select_related().get(slug=self.kwargs['slug'])
        except Forum.DoesNotExist:
            raise Http404
        return f.thread_set.select_related().all()
    def get_context_data(self, **kwargs):
        try:
            f = Forum.objects.for_groups(self.request.user.groups.all()).select_related().get(slug=self.kwargs['slug'])
        except Forum.DoesNotExist:
            raise Http404
        form = CreateThreadForm()
        child_forums = f.child.for_groups(self.request.user.groups.all())
        extra_context = {
            'forum': f,
            'child_forums': child_forums,
            'form': form,
            'login': {
                'reason': 'create a new thread',
                'next': f.get_absolute_url(),
            },
            'section': 'forum',
        }
        context = super(ForumView, self).get_context_data()
        for key in extra_context:
            context[key] = extra_context[key]
        return context

在修改后的代码中,我将变量名替换为简单的字符串,例如将"login"替换为"login_info"。这样一来,错误消失了,我的代码能够正常运行。

代码例子

class ForumView(ListView):
    context_object_name = 'forum'
    template_name = 'forum/thread_list.html',
    paginate_by = FORUM_PAGINATION
    def get_queryset(self):
        try:
            f = Forum.objects.for_groups(self.request.user.groups.all()).select_related().get(slug=self.kwargs['slug'])
        except Forum.DoesNotExist:
            raise Http404
        return f.thread_set.select_related().all()
    def get_context_data(self):
        try:
            f = Forum.objects.for_groups(self.request.user.groups.all()).select_related().get(slug=self.kwargs['slug'])
        except Forum.DoesNotExist:
            raise Http404
        form = CreateThreadForm()
        child_forums = f.child.for_groups(self.request.user.groups.all())
        extra_context = {
            'forum': f,
            'child_forums': child_forums,
            'form': form,
            'login_info': {
                'reason': 'create a new thread',
                'next': f.get_absolute_url(),
            },
            'section': 'forum',
        }
        context = super(ForumView, self).get_context_data()
        for key in extra_context:
            context[key] = extra_context[key]
        return context