我在提交表单时收到此错误。我知道到底是什么导致了这个错误,但我似乎迷失在这里。实际上,我正在尝试将 M2M 字段用作我表单中的字符字段。根据文档,M2M 字段仅采用有效 ID 列表,并传递文本列表。据我所知,这是导致错误的主要原因。知道如何摆脱这个错误
我有一个模型结构:
class Question(models.Model):
topic = models.ForeignKey(Topic, null=True, blank=True)
tag_name = models.ManyToManyField(Tag)
question = models.CharField(max_length = 200)
class Tag(models.Model):
tag_name = models.CharField(max_length = 200)
在 forms.py 中我有:
class QuestionForm(forms.ModelForm):
tag_name = forms.CharField(widget = forms.TextInput)
class Meta:
model = Question
def clean_tag_name(self):
data = self.cleaned_data
tag_name = data.get('tag_name', None)
if tag_name is not None:
for tags in tag_name.split(','):
try:
tag = Tag.objects.get(tag_name=tags)
except Tag.DoesNotExist:
tag = Tag.objects.create(tag_name = tags)
return tag_name
def save(self, commit=True):
ints = super(QuestionForm, self).save(commit=commit)
tags = self.cleaned_data.get('tag_name', None)
if tags is not None:
for tag in tags.split(","):
tag = QuestionForm.objects.create(name=tag_name)
ints.tag_name.add(tag)
ints.save()
return ints
请您参考如下方法:
您的代码片段有一些缺陷:
您不能执行 QuestionForm.objects.create(name=tag_name) 因为 QuestionForm 不是模型并且没有 objects 属性.
您可能想编写 Question.objects.create(name=tag_name) 但这不会很好,因为 Question 没有字段 name 并且此时您没有名为 tag_name 的变量。
此外,在您的 clean() 方法中,您确保用户输入的标签存在于数据库中,但在您尝试的 save() 方法中将标签名称(如字符串)而不是标签对象添加到 M2M 字段。你不能那样做。 M2M 字段的 .add() 方法需要一个 Tag 模型的实例。这意味着,在您的 .save() 方法中,您必须再次拆分标签字符串,然后从数据库中获取 Tag 对象并将这些实例添加到 Question 您刚刚创建的实例。
试试这个:
首先更改class Meta:
class Meta:
model = Question
fields = ['topic', 'question']
这确保表单不会尝试保存 tag_name 字段。这很重要,否则下面的 super() 调用会尝试向 M2M 字段添加类似 tag1, tag2, foobar 的东西,这是不可能的(记住,你可以't 将字符串添加到 M2M 字段,您只能添加实例)。
然后更改保存方式:
def save(self, *args, **kwargs):
obj = super(QuestionForm, self).save(*args, **kwargs)
tags = self.cleaned_data.get('tag_name', None)
if tags:
for tag in tags.split(","):
tag = Tag.objects.get(tag_name=tag)
obj.tag_name.add(tag)
return obj
