【问题标题】:Django UpdateView "__init__() takes at least 2 arguments (1 given)"Django UpdateView“__init__() 至少需要 2 个参数(1 个给定)”
【发布时间】:2016-05-28 22:02:13
【问题描述】:

在我过滤 forms.py 中的外键字段“事件”之前,我用于编辑任务的 UpdateView 工作正常(以确保用户只能将任务与属于他们的事件相关联)。现在它抛出了

__init__() takes at least 2 arguments (1 given)

尝试编辑任务时出错。请帮忙。

Models.py

class Event(models.Model):
    host = models.ForeignKey('auth.User')
    title = models.CharField(max_length=70)
    description = models.TextField(max_length=200)
    venue = models.CharField(max_length=70, blank=True, null=True)
    date = models.DateField(blank=True, null=True, verbose_name="Date (DD/MM/YYYY)")
    category = models.CharField(max_length=3, choices=event_cat)

    def __unicode__(self):
            return self.title

class Task(models.Model):
    host = models.ForeignKey('auth.User')
    title = models.CharField(max_length=70)
    description = models.TextField(max_length=200)
    event = models.ForeignKey(Event)
    due_date = models.DateField(verbose_name="Date Due (DD/MM/YYYY, eg 31/12/2016)")
    due_time = models.TimeField(verbose_name="Time Due (HH:MM 24 hour format, e.g 14:30")
    status = models.CharField(max_length=3, choices=task_status)

    def __unicode__(self):
            return self.title

Forms.py

task_status = (  
    ('Pen', 'Pending'),
    ('Pro', 'In Progress'),
    ('Com', 'Completed'),
    ('Ove', 'Overdue'),
)

class TaskForm(forms.ModelForm):

    status = forms.ChoiceField(choices=task_status)

    class Meta:
        model = Task
        fields = ('title','description','event','due_date','due_time','status')

    def __init__(self, host, *args, **kwargs):
            super(TaskForm, self).__init__(*args, **kwargs)
            self.fields['event'].queryset = Event.objects.filter(host=host)
            self.fields['due_date'].widget.format = '%d/%m/%Y'
            self.fields['due_date'].input_formats = ['%d/%m/%Y']

            def get_date(self):
                return self.modified.date()

    def clean_date(self):
            date = self.cleaned_data['due_date']
            if date:
                if date < datetime.date.today():
                    raise forms.ValidationError("The date cannot be in the past!")
                return date
            else:
                return date

Views.py

class edit_task(UpdateView):
    model = Task
    form_class = TaskForm
    success_url = reverse_lazy('tasks')
    template_name = 'dashboard/task_edit.html'

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        return super(edit_task, self).get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        return super(edit_task, self).post(request, *args, **kwargs)

Urls.py

url(r'^dashboard/tasks/edit/(?P<pk>\d+)/$', views.edit_task.as_view(), name='edit_task')

追溯:

File ".../lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File ".../lib/python2.7/site-packages/django/views/generic/base.py" in view
  71.             return self.dispatch(request, *args, **kwargs)
File ".../lib/python2.7/site-packages/django/views/generic/base.py" in dispatch
  89.         return handler(request, *args, **kwargs)
File ".../views.py" in get
  149.         return super(edit_task, self).get(request, *args, **kwargs)
File ".../lib/python2.7/site-packages/django/views/generic/edit.py" in get
  268.         return super(BaseUpdateView, self).get(request, *args, **kwargs)
File ".../lib/python2.7/site-packages/django/views/generic/edit.py" in get
  205.         form = self.get_form()
File ".../lib/python2.7/site-packages/django/views/generic/edit.py" in get_form
  74.         return form_class(**self.get_form_kwargs())

Exception Type: TypeError at /dashboard/tasks/edit/7/
Exception Value: __init__() takes at least 2 arguments (1 given)

【问题讨论】:

  • 您需要覆盖视图的get_form_kwargs 方法以提供您添加到表单类的__init__ 方法中的host kwarg
  • 谁会将host 参数传递给表单的__init__?肯定不是 get_form 方法,正如你所看到的 ...return form_class(**self.get_form_kwargs()) here
  • 我认为host = kwargs.pop('host') 比明确传递host 更好。检查stackoverflow.com/questions/5806224/…
  • host 参数从何而来?网址参数?我在 url 模式中看不到它(只有 pk 存在)

标签: python django foreign-keys


【解决方案1】:

Task 模型有一个指向 host 的外键。由于这是一个更新视图,我认为您实际上不需要将 host 传递给模型表单的 __init__ 方法。请改用self.instance.host

class TaskForm(forms.ModelForm):
    ...
    def __init__(self, *args, **kwargs):
        super(TaskForm, self).__init__(*args, **kwargs)
        self.fields['event'].queryset = Event.objects.filter(host=self.instance.host)
        ...

如果您确实需要将host 传递给模型表单,那么您可以覆盖get_form_kwargs。由于host 似乎是登录用户,您可以这样做:

class EditTask(UpdateView):  
    # since this is a class, EditTask is a better name than edit_task
    ...
    def get_form_kwargs(self):
        kwargs = super(EditTask, self).get_form_kwargs()
        kwargs['host'] = self.request.user
        return kwargs

【讨论】:

  • 将此添加到查看:def get_form_kwargs(self, **kwargs): kwargs = super(EditTask, self).get_form_kwargs(**kwargs) kwargs['host'] = self.request.user return kwargs
  • 我的例子丢失了return kwargs,我现在已经修复了。您不应将 **kwargs 添加到函数签名中,或将 kwargs 传递给 super() 调用。
猜你喜欢
  • 1970-01-01
  • 2012-10-08
  • 2013-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-25
相关资源
最近更新 更多