Reputation: 3938
I have the following Django code (django version 1.11) of a form:
class MyDocumentUpdateView(UpdateView):
""" We extend UpdateView as we need to pass self.object in context as resource """
model = MyDocument
def get_context_data(self, **context):
context[self.context_object_name] = self.object
context['resource'] = self.object
#context['form'] = self.get_form() <-- if I uncomment this it works
return context
class DocumentUpdateView(MyDocumentUpdateView):
form_class = MyDocumentForm
def form_valid(self, form):
doc = form.save(commit=False)
doc.owner = self.request.user
updateMyDocument(doc, form)
return HttpResponseRedirect(
reverse(
'mydocs_detail',
args=(
self.object.slug,
)))
When I run this code, I get an error:
'str' object has no attribute 'fields'
I realized that this error related with the return of the context variable. For some reason the context dictionary does not include the 'form'. As indicated in the documentation:
get_context_data(**kwargs)¶
Calls get_form() and adds the result to the context data with the name ‘form’.
But in my case the context dictionary does not include the 'form'.
If I use the get_form() def, then everything works:
context['form'] = self.get_form()
But this seems like an overkill to me and I want to dig deeper on why this doesn't work.
Then I have noticed that in my case I use:
def get_context_data(self, **context):
instead of:
def get_context_data(self, **kwargs):
So I defined the context as following:
context = super(DocumentUpdateView, self).get_context_data(**kwargs)
But then I get the following error:
maximum recursion depth exceeded
Upvotes: 1
Views: 543
Reputation: 477607
So I defined the context as following:
context = super(DocumentUpdateView, self).get_context_data(**kwargs)
You used the wrong class, since you call this at the MyDocumentUpdateView
level, it should be super(MyDocumentUpdateView, self).get_context_data(**kwargs)
. So you should implement this as:
class MyDocumentUpdateView(UpdateView):
""" We extend UpdateView as we need to pass self.object in context as resource """
model = MyDocument
def get_context_data(self, **kwargs):
context = super(MyDocumentUpdateView, self).get_context_data(**kwargs)
context['resource'] = self.object
return context
That being said, the self.object
is already added to the context, by default as the name of the model (so here that would be mydocument
, and you can specify one on your own by specifying a value for the context_object_name
attribute, like:
class MyDocumentUpdateView(UpdateView):
""" We extend UpdateView as we need to pass self.object in context as resource """
model = MyDocument
context_object_name = 'resource'
in that case, the context of course has no longer the object stored under its model name (or any other name).
Upvotes: 1