【问题标题】:Django: TypeError: context must be a dict rather than strDjango:TypeError:上下文必须是 dict 而不是 str
【发布时间】:2017-11-29 20:42:14
【问题描述】:

如果 GroupMember 的对象不存在但显示此错误,我想重定向到一个 url:

TypeError: context 必须是 dict 而不是 str。

这是我的看法:

class GroupDetail(DetailView):

template_name = "group_detail.html"
model = Group

def get_context_data(self, **kwargs):
    context = super(GroupDetail, self).get_context_data(**kwargs)
    # Code
    try:
        group_member = GroupMember.objects.get(member=volunteer, group=group)
        context['group_member'] = group_member
        # Code
        return context
    except:
        return reverse('users:home')

我尝试使用 redirect 和 reverse_lazy 但显示相同的错误,我尝试使用

reverse('users:home', {}), reverse('users:home', kwargs={}) 

reverse('users:home', kwargs=None)

【问题讨论】:

    标签: python django python-2.7 python-3.x django-views


    【解决方案1】:

    首先,这总是出错,因为本地数据中没有成员或志愿者。

    其次,正确的方法是返回 None 或空字典并覆盖 render_to_response:

    from django.views.generic import DetailView
    from django.http import HttpResponseRedirect
    from django.urls import reverse
    from django.contrib.messages import warning
    
    class GroupDetail(DetailView):
        def get_context_data(self, **kwargs):
            volunteer = self.get_volunteer()  # Or something like that
            group = self.get_group()  # Or something like that
            try:
                group_member = GroupMember.objects.get(
                    member=volunteer, group=group
                )
                return super(GroupDetail, self).get_context_data(
                    group_member=group_member, **kwargs
                )
            except GroupMember.DoesNotExist:
                return None
                # All other exceptions should really be raised as they are
                # actual application errors.
    
        def render_to_response(self, context, **response_kwargs):
            if context is None:
                warning(self.request, 'You are groupless! Peer pressure incoming.')
                return HttpResponseRedirect(reverse("users:home"))
            return super(GroupDetail, self).render_to_response(
                context, **response_kwargs
            )
    

    这样,您可以充分利用 API,并且可以扩展和覆盖您需要的部分,这就是设计基于类的视图的原因。

    【讨论】:

    • 非常感谢,我认为我也可以使用 redirect(reverse_lazy('users:home'), *args, **kwargs) 来修复它,但我使用的是你编写的代码
    【解决方案2】:

    如果您的代码引发异常,它将运行return reverse('users:home'),从而产生str 数据类型。

    但是 django 文档明确指出:

    get_context_data(**kwargs)

    返回一个表示模板上下文的字典。

    你需要这样做:

    def get_context_data(self, **kwargs):
      context = super(GroupDetail, self).get_context_data(**kwargs)
      # Code
      try:
          group_member = GroupMember.objects.get(member=volunteer,group=group)
          context['group_member'] = group_member
          # Code
      finally:
          return context
    

    或者如果你想重定向,你可以这样做:

    def get_context_data(self, **kwargs):
      context = super(GroupDetail, self).get_context_data(**kwargs)
      # Code
      try:
          group_member = GroupMember.objects.get(member=volunteer,group=group)
          context['group_member'] = group_member
          # Code
      except:
          return HttpResponseRedirect(reverse('users:home'))
    

    【讨论】:

      【解决方案3】:

      get_context_data() 方法必须返回代表模板上下文的字典,而不是 URL 字符串。要重定向异常,您可以改写 get() 方法:

      from django.http HttpResponseRedirect
      
      class GroupDetail(DetailView):
          template_name = "group_detail.html"
          model = Group
      
          def get(self, request, *args, **kwargs):
              self.object = self.get_object()
              context = self.get_context_data(object=self.object)
              try:                
                  # your code            
                  return self.render_to_response(context)
              except:
                  return HttpResponseRedirect(reverse("users:home"))
      

      您可以查看DetailView及其祖先here的源代码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-11
        • 2018-04-26
        • 1970-01-01
        • 2016-02-14
        • 2017-10-02
        • 2017-07-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多