【问题标题】:Inline formset causing error: 'NoneType' object has no attribute 'is_ajax'内联表单集导致错误:“NoneType”对象没有属性“is_ajax”
【发布时间】:2019-05-08 17:02:51
【问题描述】:

我正在使用bootstrap-modal-forms 向用户展示带有一些内联表单的表单集。如果仅在原始表单中输入数据,用户可以保存表单,但如果内联表单集有数据,则会出现以下错误:

'NoneType' object has no attribute 'is_ajax'

在我尝试以模态表单实现它们之前,内联表单集工作正常。问题似乎只有在保存内联表单集(projectimages)时才出现,它是一个 NoneType。

我的意见.py

class ProjectCreate(BSModalCreateView):
    form_class = ProjectForm
    template_name = 'project_form.html'
    success_message = 'Success: %(project_name)s was created.'

    def get_success_url(self):
        return reverse_lazy('project-detail', kwargs={'project': self.object.slug})

    def get_context_data(self, **kwargs):
        data = super(ProjectCreate, self).get_context_data(**kwargs)
        if self.request.POST:
            data['projectimages'] = ProjectFormSet(self.request.POST, self.request.FILES,)
        else:
            data['projectimages'] = ProjectFormSet()
        return data

    def form_valid(self, form):
        form.instance.date_created = timezone.now()
        context = self.get_context_data()
        projectimages = context['projectimages']
        with transaction.atomic():
            self.object = form.save()

            if projectimages.is_valid():
                projectimages.instance = self.object
                projectimages.save()

        return super(ProjectCreate, self).form_valid(form)

我的表单.py

class ProjectForm(BSModalForm):
    class Meta:
        model = Project
        exclude = ['date_created', 'slug']

ProjectFormSet = inlineformset_factory(
    Project,
    ProjectImage,
    can_delete=True,
    form=ProjectForm,
    extra=1,
)

我的模型.py

class Project(models.Model):
    project_name = models.CharField(max_length=100)
    date_created = models.DateTimeField('Created on')
    slug = models.SlugField(unique=True)

    def __str__(self):
        return self.project_name

    def save(self, *args, **kwargs):
        self.slug = slugify(str(self))
        super(Project, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('project-list')

class ProjectImage(models.Model):
    image =  models.ImageField(verbose_name='Additional Images', upload_to=project_directory_path)
    project = models.ForeignKey(Project, on_delete=models.PROTECT)
    annotation = models.CharField(max_length=200, blank=True)

我希望用户能够向模态表单集添加任意数量的图像。

【问题讨论】:

  • 你能显示整个错误跟踪吗?
  • 请注意,我不清楚您为什么将 ProjectForm 用于内联表单集,即 ProjectImage

标签: python ajax django bootstrap-modal inline-formset


【解决方案1】:

BSModalForm 期望您使用request 对其进行初始化。这发生在主表单的BSModalCreateView 中,但不会发生在您的表单集中,因为您手动初始化它。

所以在初始化的时候,只需添加form_kwargs属性即可:

 if self.request.POST:
     data['projectimages'] = ProjectFormSet(
         self.request.POST, self.request.FILES,
         form_kwargs={'request': self.request})
 else:
     data['projectimages'] = ProjectFormSet(form_kwargs={'request': self.request})

请注意,我认为您在ProjectFormSet 中设置的form 是错误的,因为它应该是ProjectImage 模型的表单,而不是Project。它实际上应该被称为ProjectImageFormSet 以更好地反映它是什么。

您可能想要删除form=ProjectForm,因为它可能不需要是BSModalForm(不确定)。在这种情况下,您不应该在form_kwargs 中传递request。如果没有,您只需要创建另一个ProjectImageForm 类。

最后,您不应该return super().form_valid(),因为这将再次保存主窗体(您已经这样做了)。自己做重定向。

【讨论】:

    猜你喜欢
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 2017-09-14
    • 2021-02-17
    • 2023-02-17
    • 2022-01-21
    • 2017-12-20
    • 2022-01-12
    相关资源
    最近更新 更多