首页 文章

Django CBV - Formsets:'NoneType'对象没有属性'id'

提问于
浏览
0

我正在使用Django CBV并且我第一次尝试使用formset . 我想在同一时间用外键填充两种形式作为两者之间的共同元素 .

我有2个型号:

class Publication(models.Model):
    title = models.CharField(max_length=512, verbose_name=_('title'), null=False, unique=True)
    description = models.TextField(verbose_name=_('description'), null=True)
    download_limit = models.IntegerField(verbose_name=_('download limit'), null=True)
    time_limit = models.IntegerField(verbose_name=_('expiration delay'), null=True)
    category = models.ForeignKey(Category, verbose_name=_('category'), null=False)
    nb_document = models.IntegerField(verbose_name=_('number of document'), default=0)
    creation_date = models.DateTimeField(auto_now_add=True, verbose_name=_('creation date'), null=False)
    modification_date = models.DateTimeField(auto_now=True, verbose_name=_('modification date'), null=False)

    class Meta:
        verbose_name = _('publication')
        verbose_name_plural = _('publication')

    def __str__(self):
        return f"{self.title}"


class Document(models.Model):

    FORMAT_CHOICES = (
        ('pdf', 'pdf'),
        ('epub', 'epub'),
    )
    edqm_id = models.CharField(max_length=12, verbose_name=_('publication ID'), unique=True, default='')
    language = models.CharField(max_length=2, verbose_name=_('language'), null=False)
    format = models.CharField(max_length=10, verbose_name=_('format'), choices=FORMAT_CHOICES, null=False)
    title = models.CharField(max_length=512, verbose_name=_('title'), null=False)
    publication = models.ForeignKey(Publication, verbose_name=_('publication'), null=False, related_name='documents')
    upload = models.FileField(upload_to='media/', validators=[validate_file_extension])
    creation_date = models.DateTimeField(auto_now_add=True, verbose_name=_('creation date'), null=False)
    modification_date = models.DateTimeField(auto_now=True, verbose_name=_('modification date'), null=False)

    class Meta:
        verbose_name = _('document')
        verbose_name_plural = _('document')

    def __str__(self):
        return f"{self.edqm_id} : {self.title} - {self.publication}"

我在我的表单python文件中定义了formset:

class PublicationForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['category'].empty_label = _('Select a category')  # Modify initial empty_label

    class Meta:
        model = Publication
        fields = ['title', 'category']


class DocumentForm(forms.ModelForm):

    class Meta:
        model = Document
        fields = ['publication', 'edqm_id', 'language', 'format', 'title', 'upload']


DocumentFormSet = inlineformset_factory(Publication, Document, form=DocumentForm, extra=1)

最重要的是,我的视图是在cruds.py文件中定义的,如下所示:

class PublicationCreateView(EdqmCreateView):

    model = Publication
    template_name = 'freepub/publication_form.html'

    def get_context_data(self, **kwargs):
        context = super(PublicationCreateView, self).get_context_data(**kwargs)

        if self.request.POST :
            context['document_form'] = DocumentFormSet(self.request.POST, self.request.FILES)
        else:
            context['document_form'] = DocumentFormSet()
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        document = context['document_form']
        if document.is_valid():
            document.instance = self.object
            document.save()
        return super(PublicationCreateView, self).form_valid(form)

    def get_success_url(self):
        return reverse('publication-list-crud')




class PublicationCRUDView(MainConfigCRUDManager):
    """ CRUD views for Publication """
    model = Publication
    default_sort_params = ('category', 'asc')

    templates = {'create': 'freepub/publication_form.html'}

    custom_views = {'create': PublicationCreateView}

    #queryset = Publication.objects.annotate(nb_documents=Count('documents'))

    # Configuration of fields
    search_fields = ['category', 'title']
    list_fields = ['category', 'title', 'creation_date', 'modification_date', 'nb_document']
    update_fields = ['category', 'title']


class DocumentCRUDView(MainConfigCRUDManager):
    """ CRUD views for Document """
    model = Document
    default_sort_params = ('title', 'asc')

    templates = {'create': 'freepub/publication_form.html'}

    custom_views = {'create': PublicationCreateView}

    # Configuration of fields
    search_fields = ['edqm_id', 'title', 'language', 'publication_id.title', 'format']
    list_fields = ['edqm_id', 'title', 'publication', 'language', 'format']
    update_fields = ['publication', 'edqm_id', 'title', 'language', 'format', 'upload']

模板很好地展示了常见的formset,但是当我想提交这个组合表单时,我遇到了这个问题:

异常值:'NoneType'对象没有属性'id'

这是回溯:

回溯:内部41中的文件“/home/ValentinJUNGBLUTH/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/core/handlers/exception.py”.response = get_response(request)File “/home/ValentinJUNGBLUTH/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/core/handlers/base.py”在_get_response 187. response = self.process_exception_by_middleware(e,request)File _get_response 185中的“/home/ValentinJUNGBLUTH/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/core/handlers/base.py” . response = wrapped_callback(request,* callback_args,** callback_kwargs)文件“/home/ValentinJUNGBLUTH/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/views/generic/base.py”在视图68中 . 返回self.dispatch(request,* args,** kwargs)在调度56中输入文件“/home/ValentinJUNGBLUTH/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/contrib/auth/mixins.py” . 返回super(LoginRequiredMixin) ,self).dispatch(request,* args,** kwargs)文件“/home/ValentinJUNGBLUTH/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/contrib/auth/mixins.py”在dispatch 116中 . 返回super(UserPassesTestMixin,self).dispatch(request ,* args,** kwargs)在调度88中输入“/home/ValentinJUNGBLUTH/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/views/generic/base.py” . 返回处理程序(request,* args,** kwargs)文件“/home/ValentinJUNGBLUTH/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/views/generic/edit.py”在第217页 . return super(BaseCreateView,self).post(request,* args,** kwargs)file“/home/ValentinJUNGBLUTH/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/views/generic / postit.py“在帖子183.返回self.form_valid(form)文件”/home/ValentinJUNGBLUTH/Bureau/Projets/Publication/publication/src/web/freepub/cruds.py“in form_valid 49. document.save() sav中的文件“/home/ValentinJUNGBLUTH/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/forms/models.py” e 666. return self.save_existing_objects(commit)self.save_new_objects(commit)file“/home/ValentinJUNGBLUTH/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/forms/models.py”在save_new_objects 800中.self.new_objects.append(self.save_new(form,commit = commit))文件“/home/ValentinJUNGBLUTH/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/forms /models.py“in save_new 946. pk_value = getattr(self.instance,self.fk.remote_field.field_name)异常类型:/ crud / publication / create / Exception中的AttributeError值:'NoneType'对象没有属性'id'

我不太了解 id 的定义以及如何解决这个问题 .

谢谢

1 回答

  • 0

    我找到了答案,但我不知道为什么它现在有效,而不是之前 .

    以前的 form_valid() 功能:

    def form_valid(self, form):
            context = self.get_context_data()
            document = context['document_form']
            if document.is_valid():
                document.instance = self.object
                document.save()
            return super(PublicationCreateView, self).form_valid(form)
    

    这是我的新 form_valid() 功能:

    def form_valid(self, form):
        context = self.get_context_data()
        document = context['document_form']
        if document.is_valid():
            self.object = form.save() #I added this line
            document.instance = self.object
            document.save()
        return super(PublicationCreateView, self).form_valid(form)
    

相关问题