Django CBV - 表单集:'NoneType' 对象没有属性 'id'
Django CBV - Formsets : 'NoneType' object has no attribute 'id'
我正在使用 Django CBV,这是我第一次尝试使用表单集。
我想同时填写两个表格,外键作为两者之间的公共元素。
我有 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'),
)
age_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.age_id} : {self.title} - {self.publication}"
我在我的表单 python 文件中定义了表单集:
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', 'age_id', 'language', 'format', 'title', 'upload']
DocumentFormSet = inlineformset_factory(Publication, Document, form=DocumentForm, extra=1)
最重要的是,我的视图是在 cruds.py 文件中定义的,如下所示:
class PublicationCreateView(AgeCreateView):
model = Publication
template_name = 'app/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': 'app/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': 'app/publication_form.html'}
custom_views = {'create': PublicationCreateView}
# Configuration of fields
search_fields = ['age_id', 'title', 'language', 'publication_id.title', 'format']
list_fields = ['age_id', 'title', 'publication', 'language', 'format']
update_fields = ['publication', 'age_id', 'title', 'language', 'format', 'upload']
模板显示良好,具有通用的表单集,但是当我想提交这个组合表单时,我遇到了这个问题:
Exception Value: 'NoneType' object has no attribute 'id'
这是回溯:
Traceback:
File
"/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/core/handlers/exception.py"
in inner
41. response = get_response(request)
File
"/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/core/handlers/base.py"
in _get_response
187. response = self.process_exception_by_middleware(e, request)
File
"/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/core/handlers/base.py"
in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File
"/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/views/generic/base.py"
in view
68. return self.dispatch(request, *args, **kwargs)
File
"/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/contrib/auth/mixins.py"
in dispatch
56. return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
File
"/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/contrib/auth/mixins.py"
in dispatch
116. return super(UserPassesTestMixin, self).dispatch(request, *args, **kwargs)
File
"/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/views/generic/base.py"
in dispatch
88. return handler(request, *args, **kwargs)
File
"/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/views/generic/edit.py"
in post
217. return super(BaseCreateView, self).post(request, *args, **kwargs)
File
"/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/views/generic/edit.py"
in post
183. return self.form_valid(form)
File
"/home/Bureau/Projets/Publication/publication/src/web/app/cruds.py"
in form_valid
49. document.save()
File
"/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/forms/models.py"
in save
666. return self.save_existing_objects(commit) + self.save_new_objects(commit)
File
"/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/forms/models.py"
in save_new_objects
800. self.new_objects.append(self.save_new(form, commit=commit))
File
"/home/.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)
Exception Type: AttributeError at /crud/publication/create/ Exception
Value: 'NoneType' object has no attribute 'id'
我不太明白 id
的定义以及如何解决这个问题。
谢谢
我找到了答案,但我不知道为什么它现在有效而不是以前。
上一个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)
我正在使用 Django CBV,这是我第一次尝试使用表单集。 我想同时填写两个表格,外键作为两者之间的公共元素。
我有 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'),
)
age_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.age_id} : {self.title} - {self.publication}"
我在我的表单 python 文件中定义了表单集:
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', 'age_id', 'language', 'format', 'title', 'upload']
DocumentFormSet = inlineformset_factory(Publication, Document, form=DocumentForm, extra=1)
最重要的是,我的视图是在 cruds.py 文件中定义的,如下所示:
class PublicationCreateView(AgeCreateView):
model = Publication
template_name = 'app/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': 'app/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': 'app/publication_form.html'}
custom_views = {'create': PublicationCreateView}
# Configuration of fields
search_fields = ['age_id', 'title', 'language', 'publication_id.title', 'format']
list_fields = ['age_id', 'title', 'publication', 'language', 'format']
update_fields = ['publication', 'age_id', 'title', 'language', 'format', 'upload']
模板显示良好,具有通用的表单集,但是当我想提交这个组合表单时,我遇到了这个问题:
Exception Value: 'NoneType' object has no attribute 'id'
这是回溯:
Traceback:
File "/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner 41. response = get_response(request)
File "/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 187. response = self.process_exception_by_middleware(e, request)
File "/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/views/generic/base.py" in view 68. return self.dispatch(request, *args, **kwargs)
File "/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/contrib/auth/mixins.py" in dispatch 56. return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
File "/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/contrib/auth/mixins.py" in dispatch 116. return super(UserPassesTestMixin, self).dispatch(request, *args, **kwargs)
File "/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/views/generic/base.py" in dispatch 88. return handler(request, *args, **kwargs)
File "/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/views/generic/edit.py" in post 217. return super(BaseCreateView, self).post(request, *args, **kwargs)
File "/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/views/generic/edit.py" in post 183. return self.form_valid(form)
File "/home/Bureau/Projets/Publication/publication/src/web/app/cruds.py" in form_valid 49. document.save()
File "/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/forms/models.py" in save 666. return self.save_existing_objects(commit) + self.save_new_objects(commit)
File "/home/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/forms/models.py" in save_new_objects 800. self.new_objects.append(self.save_new(form, commit=commit))
File "/home/.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)
Exception Type: AttributeError at /crud/publication/create/ Exception Value: 'NoneType' object has no attribute 'id'
我不太明白 id
的定义以及如何解决这个问题。
谢谢
我找到了答案,但我不知道为什么它现在有效而不是以前。
上一个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)