如何解决Django:将项目保存到数据库,外键混淆 注意你哪里出错了:
所以我写了一个小的 Django 应用程序作为某种在线购物清单。基本上,您有两个文本输入,您可以在其中输入要购买的项目和第二个 CharField 中的金额。还有一个下拉菜单,允许您为您的项目选择一个类别,使列表更清晰。下拉菜单是从数据库填充的。现在一切似乎都正常(将项目添加到列表以及查询它们),唯一的问题是应用程序似乎单独保存了类别,使可用类别的列表越来越大(通过将新添加的类别 ID 添加到它)。 可以在这里看到: https://imgur.com/a/xlsSepv
文本是我为用户添加的类别,而数字是将项目添加到数据库后添加的类别。
这是我的models.py文件
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=20)
tag = models.CharField(max_length=2)
def __str__(self):
return self.name
class Item(models.Model):
text = models.CharField(max_length=40)
count = models.CharField(max_length=100)
category = models.ForeignKey(Category,on_delete=models.CASCADE)
complete = models.BooleanField(default=False)
def __str__(self):
return self.text
这是我的views.py
@require_POST
def addItem(request):
form = ItemForm(request.POST)
if form.is_valid():
category = Category(name=request.POST['category'])
category.save()
new_item = Item(text=request.POST['text'],count=request.POST['count'],category=category)
new_item.save()
这是我的 forms.py 文件
from django import forms
from .models import Category
class ItemForm(forms.Form):
text = forms.CharField(max_length=40,widget=forms.TextInput(
attrs={'class' : 'form-control','placeholder' : 'Gib einen neuen Gegenstand ein (z.B. Wasser)','aria-label' : 'Item','aria-describedby' : 'add-btn'}))
count = forms.CharField(max_length=100,'placeholder' : 'Gib eine Anzahl ein (z.B. 5)','value' : '1','aria-label' : 'Count','aria-describedby' : 'add-btn'}))
category = forms.ModelChoiceField(queryset=Category.objects.all(),initial=0,widget=forms.Select(attrs={'class' : 'form-control','aria-label' : 'Kategorie','aria-describedby' : 'add-btn'}
))
我知道我的问题很可能是我在将新项目保存到数据库之前保存了类别(在我的 views.py 文件中)。但是,如果我删除该 category.save() 语句,调试器会告诉我
“save() 被禁止,以防止由于未保存的相关对象“类别”而导致数据丢失。”
如果工作正常,其他一切。我真的无法理解我做错了什么。因此,非常感谢任何帮助。
如果我错过了向您传递任何信息,请告诉我。
提前致谢!
解决方法
由于您的 Form
用于保存 Model
的数据,因此最合乎逻辑的步骤是使用 ModelForm
:
class ItemForm(forms.ModelForm):
text = forms.CharField(max_length=40,widget=forms.TextInput(
attrs={'class' : 'form-control','placeholder' : 'Gib einen neuen Gegenstand ein (z.B. Wasser)','aria-label' : 'Item','aria-describedby' : 'add-btn'}))
count = forms.CharField(max_length=100,'placeholder' : 'Gib eine Anzahl ein (z.B. 5)','value' : '1','aria-label' : 'Count','aria-describedby' : 'add-btn'}))
category = forms.ModelChoiceField(queryset=Category.objects.all(),initial=0,widget=forms.Select(attrs={'class' : 'form-control','aria-label' : 'Kategorie','aria-describedby' : 'add-btn'}
))
class Meta:
model = Item
exclude = ['complete']
注意:如果您不提供字段定义,ModelForm
将根据模型自动生成它们。
现在在您看来:
@require_POST
def addItem(request):
form = ItemForm(request.POST)
if form.is_valid():
new_item = form.save()
注意你哪里出错了:
您遇到的问题是您正在保存类别!而不是在表单中使用类别。当您使用表单并且 is_valid()
返回 True
时,form.cleaned_data
会填充经过验证和清理的数据。因此,如果您编写了 category = form.cleaned_data['category']
,您将获得正确的 Category
实例,您可以直接使用它来保存。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。