【问题标题】:django forms and __init__ function: unexpected keyword argument 'user'django 表单和 __init__ 函数:意外的关键字参数“用户”
【发布时间】:2015-07-15 21:25:40
【问题描述】:

我遵循 kenneth love 速成课程,但遇到无法解决的意外错误:

"init() 得到了一个意外的关键字参数 'user'"

这里是表单类:

class TalkTalkListForm(forms.ModelForm):
    class Meta:
        model = models.Talk
        fields = ('talk_list',)

    def __init__(self, *args, **kwargs):
        super(TalkTalkListForm, self).__init__(*args, **kwargs)
        self.fields['talk_list'].queryset = (
            self.instance.talk_list.user.lists.all())

        self.helper = FormHelper()
        self.helper.layout = Layout(
            'talk_list',
            ButtonHolder(
                Submit('move', 'Move', css_class='btn-primary')
            )
        )

这里是 Talk 模型:

class Talk(models.Model):
    ROOM_CHOICES = (
            ('BS1_O', 'BS1_O'),
            ('BS1TC', 'BS1TC'),
            ('BS3_O', 'BS3_O'),
            ('BS3TC', 'BS3TC'),
    )
    talk_list = models.ForeignKey(TalkList, related_name='talks')
    name = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255, blank=True)
    when = models.DateTimeField()
    room = models.CharField(max_length=5, choices=ROOM_CHOICES)
    host = models.CharField(max_length=255)
    talk_rating = models.IntegerField(blank=True, default=0)
    speaker_rating = models.IntegerField(blank=True, default=0)   

    notes = models.TextField(blank=True, default='')
    notes_html = models.TextField(blank=True, default='', editable=False)

    class Meta:
        ordering = ('when', 'room')
        unique_together = ('talk_list', 'name')

    def __unicode__(self):
        return self.name

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        self.notes_html = mistune.markdown(self.notes)
        super(Talk, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('talks:talks:detail', kwargs={'slug': self.slug})       

    @property
    def overall_rating(self):
        if self.talk_rating and self.speaker_rating:
            return (self.talk_rating + self.speaker_rating) / 2
        return 0  

我可以看到 Talk 没有属性“用户”,但我以某种方式将“用户”属性传递给 init。是问题的原因吗?

我知道 kwargs 是命名参数,因此不期望的命名参数会引发错误,但我不知道如何摆脱错误。

更新:

class TalkDetailView(views.LoginRequiredMixin, generic.DetailView):
    http_method_names = ['get', 'post']
    model = models.Talk

    def get_queryset(self):
        return self.model.objects.filter(talk_list__user=self.request.user)

    def get_context_data(self, **kwargs):
        context = super(TalkDetailView, self).get_context_data(**kwargs)
        obj = context['object']
        rating_form = forms.TalkRatingForm(self.request.POST or None,instance=obj)

        list_form = forms.TalkTalkListForm(self.request.POST or None,instance=obj)        

        context.update({
            'rating_form': rating_form,
            'list_form': list_form
        })
        return context

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        if 'save' in request.POST:
            talk_form = forms.TalkRatingForm(request.POST or None,
                                             instance=self.object)
            if talk_form.is_valid():
                talk_form.save()

        if 'move' in request.POST:
            list_form = forms.TalkTalkListForm(request.POST or None,
                                               instance=self.object,
                                               user=request.user)
            if list_form.is_valid():
                list_form.save()

        return redirect(self.object)

【问题讨论】:

  • 您的视图中某处看起来有问题...显示视图代码
  • 我刚刚用视图代码更新了这个问题。此行中的 user=request.user 有问题吗: list_form = forms.TalkTalkListForm(request.POST or None, instance=self.object, user=request.user) ?

标签: django forms init


【解决方案1】:

我不明白,如果您已经通过request.user 过滤了查询集,为什么还要将request.user 放在init 中== return self.model.objects.filter(talk_list__user=self.request.user)

无论如何...

1) 如果你想以__init__ 的形式访问kwarg,你应该在调用super 之前pop 它...

def __init__(self, *args, **kwargs):
    user = kwargs.pop('user', False)
    # now you have removed it from kwargs and `super` call will work as expected
    super(TalkTalkListForm, self).__init__(*args, **kwargs)
    # do smth with `user`

2) 如果您想将request.user 保存到对象中,请在您的视图中这样做:

if list_form.is_valid():
    obj = list_form.save()
    obj.talk_list.user = request.user
    obj.save()

【讨论】:

  • 两者,或者从 'list_form = forms.TalkTalkListForm(request.POST or None, instance=self.object, user=request.user)' 中删除 'user=request.user' 或者使用 pop就像你提到的那样对我来说现在很好。我不知道我可以用 2) 做什么?感谢您的帮助!
猜你喜欢
  • 2021-11-17
  • 2012-02-10
  • 2021-10-29
  • 2015-01-27
  • 1970-01-01
  • 2018-09-02
  • 2013-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多