Django 1.11.17 TypeError: «контекст должен быть диктатом, а не контекстом», за исключением того, что это DICT - PullRequest
0 голосов
/ 06 декабря 2018

Я недавно перешел с Django 1.9 на 1.11.17, и меня беспокоит одна вещь.Есть эта ошибка, которая говорит:

TypeError at /somepath
context must be a dict rather than Context

Строка, которая ее выдает:

return render(request=request, template_name="mytemplate.html", context={"form": form, "update": updateType})

Есть много ответов на SO, где люди используют RequestContext или Context вместо dict для context и переход к диктату решает их проблему.Но не для меня.Здесь я почти уверен, что мои context на самом деле диктат.Что интересно, если я изменю его на:

return render(request=request, template_name="mytemplate.html", context={})

Ошибка исчезает, но, очевидно, позже вызывает другую ошибку.Ребята, вы понимаете, что я здесь делаю неправильно?

РЕДАКТИРОВАТЬ: Мой импорт:

from django.shortcuts import render, render_to_response
from django.template.context import RequestContext, Context

Я пробовал бот render и render_to_response с аналогичным эффектом.Также использование Context или RequestContext дало похожую ошибку.

EDIT2: Дополнительный код для справки

from django.http import (
    HttpResponseRedirect,
    HttpResponseBadRequest,
)
from django.shortcuts import render, render_to_response
from django.template import RequestContext, Context
from django.utils.html import escape

# some more imports, but from local files, not django

def update_my_template(request):
    user = request.user
    # preform some checks for user
    ...

    if request.method == "GET":
        updateType = request.GET.get("id")
        if updateType:
            form = None
            if updateType == "something":
                form = SomeForm(user)
            if updateType == "something else":
                form = DifferentForm()
            if form is None:
                return HttpResponseRedirect("/somepage")

            # This was the code that worked in 1.9
            rctx = RequestContext(
                request, {"form": form, "update": updateType}
            )
            return render_to_response("mytemplate.html", rctx)



    # some different cases, but the error is thrown already
...

Ни одна из этих работ:

dictctx = {"form": form, "update": updateType}
return render(request=request, template_name="mytemplate.html", dictctx)

.

ctx = Context({"form": form, "update": updateType})
return render(request=request, template_name="mytemplate.html", ctx)

.

ctx = Context({"form": form, "update": updateType})
return render(request=request, template_name="mytemplate.html", ctx.flatten())

.

rctx = RequestContext(request, {"form": form, "update": updateType})
return render_to_response("mytemplate.html", rctx.flatten())

Ответы [ 3 ]

0 голосов
/ 06 декабря 2018

Всегда передавайте переменные / значения в параметрах.Но Вы даете оба одновременно.Попробуйте это следующим образом: ...

return render (request = request, template_name = "mytemplate.html", {"form": form, "update": updateType})

Или

context = {"form": form, "update": updateType} return render (запрос = запрос, template_name = "mytemplate.html", context)

0 голосов
/ 06 декабря 2018

Хорошо, после еще нескольких копаний (в «нерешенных» вопросах) я нашел этот камень .И да, это было решением моей проблемы.В основном у меня была строка {{form|bootstrap}} в моем mytemplate.html, которая вызывала это.

Еще лучше, обновление django-bootstrap-form до версии 3.4 позволило мне сохранить {{form|bootstrap}} и избавиться от ошибки.

0 голосов
/ 06 декабря 2018

Логика render отличается в зависимости от того, что вы передаете render:

def render(self, context):
        "Display stage -- can be called many times"
        with context.render_context.push_state(self):
            if context.template is None:
                with context.bind_template(self):
                    context.template_name = self.name
                    return self._render(context)
            else:
                return self._render(context)

, и похоже, что вы можете изменить свой параметр template_name, чтобы он был просто name, но у вашего объекта нет значения context.render_context, поэтому было бы лучше создать и использовать экземпляр Context

https://docs.djangoproject.com/en/1.11/_modules/django/template/base/#Template.render

Документы показываютпередача фактического экземпляра Context, поэтому я рекомендую вам сделать это в своем коде, а не просто передавать dict:

>>> from django.template import Context, Template
>>> template = Template("My name is {{ my_name }}.")

>>> context = Context({"my_name": "Adrian"})
>>> template.render(context)
"My name is Adrian."

>>> context = Context({"my_name": "Dolores"})
>>> template.render(context)

, поэтому самый простой способ исправить ваш код будет выглядеть примерно так:

from django.template import Context
...
return render(request=request, template_name="mytemplate.html", context=Context({"form": form, "update": updateType}))
...