get_form 将 Django 升级到 1.10 后抛出 TypeError
get_form throws TypeError after upgrading Django to 1.10
我最近从 1.4 升级到 1.11(增量),从 1.9 升级到 1.10 后,我遇到了 get_form() 的问题。似乎我的上下文不包含 "form" 并且当调用超级 get_context_data 时,它会尝试传递一个空的 get_form() 调用来填写表单。知道为什么现在会出错吗?
Internal Server Error: /messages/threads/6/
Traceback (most recent call last):
File "C:\Users\LT\Envs\django111\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
response = get_response(request)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\core\handlers\base.py", line 249, in _legacy_get_response
response = self._get_response(request)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\contrib\auth\decorators.py", line 23, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\LT1\project\messages\views.py", line 93, in dispatch
return super(MemoCreateView, self).dispatch(request, *args, **kwargs)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\views\generic\base.py", line 88, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\views\generic\edit.py", line 213, in get
return super(BaseCreateView, self).get(request, *args, **kwargs)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\views\generic\edit.py", line 174, in get
return self.render_to_response(self.get_context_data())
File "C:\Users\LT1\project\messages\views.py", line 96, in get_context_data
context = super(MemoCreateView, self).get_context_data(**kwargs)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\views\generic\edit.py", line 93, in get_context_data
kwargs['form'] = self.get_form()
TypeError: get_form() takes exactly 2 arguments (1 given)
"GET /messages/threads/6/ HTTP/1.1" 500 113089
urls.py
from django.conf.urls import url, include
from django.contrib.auth.decorators import login_required
from django.views.generic import ListView
from django.views.generic.base import RedirectView
from .models import *
from .views import *
urlpatterns = [
url(r'^$', login_required(RedirectView.as_view(url='/messages/threads/')), name='messages_index'),
url(r'^threads/$', login_required(ThreadListView.as_view()), name='messages_thread_index'),
url(r'^threads/create/$', login_required(ThreadCreateView.as_view()), name='messages_thread_create'),
url(r'^threads/to-user/(?P<user_id>[0-9]+)/create/$', login_required(PrepopulatedUserThreadCreateView.as_view()), name='messages_prepopulated_user_thread_create'),
url(r'^threads/to-group/(?P<group_id>[0-9]+)/create/$', login_required(PrepopulatedGroupThreadCreateView.as_view()), name='messages_prepopulated_group_thread_create'),
url(r'^threads/(?P<thread_id>[0-9]+)/$', login_required(MemoCreateView.as_view()), name='messages_memo_index'),
url(r'^ajax/search/$', login_required(SearchView.as_view()), name='messages_ajax_search'),
url(r'^ajax/queue/$', login_required(QueueView.as_view()), name='messages_ajax_queue'),
]
views.py
class MemoCreateView(CreateView):
model = Memo
form_class = MemoForm
def dispatch(self, request, *args, **kwargs):
self.thread = Thread.objects.get(id=kwargs['thread_id'])
if not user_has_permission(request.user, self.thread, 'can_message'):
raise PermissionDenied('You do not have permission to view this thread.')
self.thread.read_by_role.users.add(request.user)
return super(MemoCreateView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(MemoCreateView, self).get_context_data(**kwargs)
context['thread'] = self.thread
context['participants_form'] = ThreadForm
return context
def get_form(self, form_class):
if self.thread:
if self.request.method == 'GET':
participants = self.thread.participant_role.users.all()
users_csv = ','.join([str(user.id) for user in self.thread.participant_role.users.all()])
return form_class({'participants': users_csv,})
'''
elif self.request.method == 'POST':
return form_class(self.request.POST, instance=self.shared_object)
else:
if self.request.method == 'POST':
return form_class(self.request.POST)
'''
return super(MemoCreateView, self).get_form(form_class)
def form_valid(self, form):
'''
self.object = form.save(commit=False)
self.object.author = self.request.user
self.object.thread = self.thread
self.object.save()
'''
memo = form.save(commit=False)
memo.author = self.request.user
memo.thread = self.thread
memo.save()
participants = []
participant_ids = form.cleaned_data['participants'].replace(' ', '').split(',')
for participant_id in participant_ids:
if participant_id:
participants.append(User.objects.get(id=participant_id))
groups = []
group_ids = form.cleaned_data['groups'].replace(' ', '').split(',')
for group_id in group_ids:
if group_id:
groups.append(Group.objects.get(id=group_id))
for group in groups:
if not user_has_permission(self.request.user, group, 'can_message'):
raise PermissionDenied('You do not have permission to message to the group "' + group.name + '"')
thread = memo.thread
#thread.subject = form.cleaned_data['subject']
thread.creator = self.request.user
thread.save()
thread.participant_role.users.add(*participants)
for group in groups:
thread.participant_role.users.add(*list(group.owner_role.users.all()))
thread.participant_role.users.add(*list(group.moderator_role.users.all()))
thread.participant_role.users.add(*list(group.member_role.users.all()))
self.success_url = thread.get_absolute_url()
return super(MemoCreateView, self).form_valid(form)
问题库行:
C:\Users\LT\Envs\django111\lib\site-packages\django\views\generic\edit.py in get_context_data
return self.render_to_response(self.get_context_data(form=form))
def get_context_data(self, **kwargs):
"""
Insert the form into the context dict.
"""
if 'form' not in kwargs:
kwargs['form'] = self.get_form() ...
return super(FormMixin, self).get_context_data(**kwargs)
class ModelFormMixin(FormMixin, SingleObjectMixin):
"""
A mixin that provides a way to show and handle a modelform in a request.
我试过将视图更改为
def get_form(self, form_class=None):
if form_class is None:
form_class = self.form_class
if self.thread:
if self.request.method == 'GET':
participants = self.thread.participant_role.users.all()
users_csv = ','.join([str(user.id) for user in self.thread.participant_role.users.all()])
return form_class({'participants': users_csv,})
'''
elif self.request.method == 'POST':
return form_class(self.request.POST, instance=self.shared_object)
else:
if self.request.method == 'POST':
return form_class(self.request.POST)
'''
return super(MemoCreateView, self).get_form(form_class)
如评论中所建议的那样,但它并没有改变任何东西。似乎 django 视图库本身正在调用一个没有参数的 get_form - 我怎样才能防止这种情况发生?
As of Django 1.8, the get_form()
method doesn’t require a form_class
to be provided anymore. As of Django 1.10,您必须在自定义 get_form
方法中为 form_class
定义默认值。
您可以按如下方式更改。
def get_form(self, form_class=None):
if form_class is None:
form_class = self.form_class
...
我最近从 1.4 升级到 1.11(增量),从 1.9 升级到 1.10 后,我遇到了 get_form() 的问题。似乎我的上下文不包含 "form" 并且当调用超级 get_context_data 时,它会尝试传递一个空的 get_form() 调用来填写表单。知道为什么现在会出错吗?
Internal Server Error: /messages/threads/6/
Traceback (most recent call last):
File "C:\Users\LT\Envs\django111\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
response = get_response(request)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\core\handlers\base.py", line 249, in _legacy_get_response
response = self._get_response(request)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\contrib\auth\decorators.py", line 23, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\LT1\project\messages\views.py", line 93, in dispatch
return super(MemoCreateView, self).dispatch(request, *args, **kwargs)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\views\generic\base.py", line 88, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\views\generic\edit.py", line 213, in get
return super(BaseCreateView, self).get(request, *args, **kwargs)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\views\generic\edit.py", line 174, in get
return self.render_to_response(self.get_context_data())
File "C:\Users\LT1\project\messages\views.py", line 96, in get_context_data
context = super(MemoCreateView, self).get_context_data(**kwargs)
File "C:\Users\LT\Envs\django111\lib\site-packages\django\views\generic\edit.py", line 93, in get_context_data
kwargs['form'] = self.get_form()
TypeError: get_form() takes exactly 2 arguments (1 given)
"GET /messages/threads/6/ HTTP/1.1" 500 113089
urls.py
from django.conf.urls import url, include
from django.contrib.auth.decorators import login_required
from django.views.generic import ListView
from django.views.generic.base import RedirectView
from .models import *
from .views import *
urlpatterns = [
url(r'^$', login_required(RedirectView.as_view(url='/messages/threads/')), name='messages_index'),
url(r'^threads/$', login_required(ThreadListView.as_view()), name='messages_thread_index'),
url(r'^threads/create/$', login_required(ThreadCreateView.as_view()), name='messages_thread_create'),
url(r'^threads/to-user/(?P<user_id>[0-9]+)/create/$', login_required(PrepopulatedUserThreadCreateView.as_view()), name='messages_prepopulated_user_thread_create'),
url(r'^threads/to-group/(?P<group_id>[0-9]+)/create/$', login_required(PrepopulatedGroupThreadCreateView.as_view()), name='messages_prepopulated_group_thread_create'),
url(r'^threads/(?P<thread_id>[0-9]+)/$', login_required(MemoCreateView.as_view()), name='messages_memo_index'),
url(r'^ajax/search/$', login_required(SearchView.as_view()), name='messages_ajax_search'),
url(r'^ajax/queue/$', login_required(QueueView.as_view()), name='messages_ajax_queue'),
]
views.py
class MemoCreateView(CreateView):
model = Memo
form_class = MemoForm
def dispatch(self, request, *args, **kwargs):
self.thread = Thread.objects.get(id=kwargs['thread_id'])
if not user_has_permission(request.user, self.thread, 'can_message'):
raise PermissionDenied('You do not have permission to view this thread.')
self.thread.read_by_role.users.add(request.user)
return super(MemoCreateView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(MemoCreateView, self).get_context_data(**kwargs)
context['thread'] = self.thread
context['participants_form'] = ThreadForm
return context
def get_form(self, form_class):
if self.thread:
if self.request.method == 'GET':
participants = self.thread.participant_role.users.all()
users_csv = ','.join([str(user.id) for user in self.thread.participant_role.users.all()])
return form_class({'participants': users_csv,})
'''
elif self.request.method == 'POST':
return form_class(self.request.POST, instance=self.shared_object)
else:
if self.request.method == 'POST':
return form_class(self.request.POST)
'''
return super(MemoCreateView, self).get_form(form_class)
def form_valid(self, form):
'''
self.object = form.save(commit=False)
self.object.author = self.request.user
self.object.thread = self.thread
self.object.save()
'''
memo = form.save(commit=False)
memo.author = self.request.user
memo.thread = self.thread
memo.save()
participants = []
participant_ids = form.cleaned_data['participants'].replace(' ', '').split(',')
for participant_id in participant_ids:
if participant_id:
participants.append(User.objects.get(id=participant_id))
groups = []
group_ids = form.cleaned_data['groups'].replace(' ', '').split(',')
for group_id in group_ids:
if group_id:
groups.append(Group.objects.get(id=group_id))
for group in groups:
if not user_has_permission(self.request.user, group, 'can_message'):
raise PermissionDenied('You do not have permission to message to the group "' + group.name + '"')
thread = memo.thread
#thread.subject = form.cleaned_data['subject']
thread.creator = self.request.user
thread.save()
thread.participant_role.users.add(*participants)
for group in groups:
thread.participant_role.users.add(*list(group.owner_role.users.all()))
thread.participant_role.users.add(*list(group.moderator_role.users.all()))
thread.participant_role.users.add(*list(group.member_role.users.all()))
self.success_url = thread.get_absolute_url()
return super(MemoCreateView, self).form_valid(form)
问题库行:
C:\Users\LT\Envs\django111\lib\site-packages\django\views\generic\edit.py in get_context_data
return self.render_to_response(self.get_context_data(form=form))
def get_context_data(self, **kwargs):
"""
Insert the form into the context dict.
"""
if 'form' not in kwargs:
kwargs['form'] = self.get_form() ...
return super(FormMixin, self).get_context_data(**kwargs)
class ModelFormMixin(FormMixin, SingleObjectMixin):
"""
A mixin that provides a way to show and handle a modelform in a request.
我试过将视图更改为
def get_form(self, form_class=None):
if form_class is None:
form_class = self.form_class
if self.thread:
if self.request.method == 'GET':
participants = self.thread.participant_role.users.all()
users_csv = ','.join([str(user.id) for user in self.thread.participant_role.users.all()])
return form_class({'participants': users_csv,})
'''
elif self.request.method == 'POST':
return form_class(self.request.POST, instance=self.shared_object)
else:
if self.request.method == 'POST':
return form_class(self.request.POST)
'''
return super(MemoCreateView, self).get_form(form_class)
如评论中所建议的那样,但它并没有改变任何东西。似乎 django 视图库本身正在调用一个没有参数的 get_form - 我怎样才能防止这种情况发生?
As of Django 1.8, the get_form()
method doesn’t require a form_class
to be provided anymore. As of Django 1.10,您必须在自定义 get_form
方法中为 form_class
定义默认值。
您可以按如下方式更改。
def get_form(self, form_class=None):
if form_class is None:
form_class = self.form_class
...