django - 在 Django 中使用 SelectMultiple 保存失败
问题描述
我在使用“选择多个字段”保存数据库数据时遇到问题我的代码如下所示:
模型.py
class Author(models.Model):
author_name = models.CharField(max_length=100)
author_lastname = models.CharField(max_length=100)
class Book(models.Model):
statement_title = models.CharField(max_length=1000, null=True, blank=True)
author = models.ManyToManyField(Author,blank=True)
表格.py
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields = ['__all__']
widgets = {
'title': forms.Textarea(attrs={'type': 'text',
'placeholder': 'Book title'}
'author': forms.SelectMultiple()
}
如果我添加一个新对象,一切都会保存但没有作者,但如果我在管理页面中保存作者,我可以在书籍详细信息视图中显示作者。
当然,我尝试了很多解决方案来解决这个问题,但没有解决我的问题。我知道我犯了一个错误,但我不知道在哪里......也许我应该在views.py中添加一些额外的东西?我将非常感谢任何提示和线索。
编辑:
我附上了 views.py (edit_book类似于add_book)。这只是一个典型的视图功能。当我尝试显示作者 ID 时,它工作正常。
视图.py
def edit_book(request, pk):
book = get_object_or_404(Book, pk=pk)
if request.method == "POST":
form = BookForm(request.POST, instance=book)
if form.is_valid():
book = form.save(commit=False)
print(">>>>>>>>>>>>>>>>>>>>>>>")
print(book.author.all)
for author in form.cleaned_data['author']:
print(author.id)
book.save()
return redirect('book_details', book.id)
else:
form = BookForm(instance=book)
return render(request,
'books/book/book_new.html',
{'form': form})
解决方案
请不要使用form.save(commit=False)
. AModelForm
只能保存ManyToManyField
s with commit=True
(或稍后 with .save_m2m()
),如Django 文档中讨论的save()
方法:
当您的模型与另一个模型具有多对多关系时,会看到使用
commit=False
的另一个副作用。如果您的模型具有多对多关系并且您指定何时保存表单,则 Django 无法立即保存多对多关系的表单数据。这是因为在实例存在于数据库中之前,无法为实例保存多对多数据。commit=False
但这里最简单的方法就是让表单本身保存对象:
def edit_book(request, pk):
book = get_object_or_404(Book, pk=pk)
if request.method == 'POST':
form = BookForm(request.POST, instance=book)
if form.is_valid():
book = form.save() # ← will save many-to-many fields
return redirect('book_details', book.id)
else:
form = BookForm(instance=book)
return render(
request,
'books/book/book_new.html',
{'form': form}
)
Django 不能保存多对多关系本身的原因是因为首先您创建的对象需要在数据库端创建,以具有主键。只有这样,联结表[wiki]才能填充元素。
推荐阅读
- ios - 扑。如何更新PageView内的GridView内的文本?
- fonts - SwiftUI:读取给定字符串的边界矩形
- vba - 从共享的 Outlook 邮箱自动下载带有特定主题的附件 PDF 文件
- javascript - 为什么对象在组件外部同步(反应)而单个变量没有?
- amazon-web-services - 如何使用 Terraform 选择未使用的 VPC CIDR 块?
- docker - 弹性用户密码不适用于我的 docker 映像
- amazon-web-services - 调用 PutBucketPolicy 操作时出错(MalformedPolicy):Policy has invalid resource
- python - 低级递归在代码中是如何工作的?
- firebase - 如何使用复选框单击更改 Firebase 中子项的值
- javascript - 如何根据本地存储中的值显示/隐藏 div?