python - Django 升级到 1.10 后 get_form 抛出 TypeError

标签 python django upgrade django-1.10

我最近从 1.4 升级到 1.11(增量),从 1.9 升级到 1.10 后,我遇到了 get_form() 问题。看来我的上下文不包含“表单”,当调用 super 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\LT\111\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\LT\111\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

url.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'),
]

View .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.

我尝试将 View 更改为

 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 View 库本身正在调用不带参数的 get_form - 我怎样才能防止这种情况发生?

最佳答案

As of Django 1.8get_form() 方法不再需要提供 form_classAs 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
    ...

关于python - Django 升级到 1.10 后 get_form 抛出 TypeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44053381/

相关文章:

python - numpy 中带有广播的双点积

python - 递归错误 : maximum recursion depth exceeded in comparison Python

python - DRF 查询集返回特定字段

php - 如何使用基于 HTML 的用户界面表示多对多记录的关系

WordPress 3.9 升级失败

java - android 计划的作业是否在应用程序升级后仍然存在?

python - 如何使用其他文件中的变量作为名称来调用函数

python - 在 Angular 4 模板中使用 django 标签?

kernel - 从 Fedora 14 升级到 15 后服务器掉落到 dracut 调试 shell

Python 3.5 async/await 与真实代码示例