Django错误:在可以使用多对多关系之前,需要为字段“…”设置一个值

当保存表单时,我得到这个错误:“”需要有一个字段的值“surveythread”之前,这种多对多的关系可以使用。

Models.py:

class SurveyResult(models.Model): stay = models.OneToOneField(Stay, related_name='survey') created = models.DateTimeField(default=datetime.now) vote = models.BooleanField(default=False) vote_service = models.BooleanField(default=False) comment = models.TextField(blank=True, null=True) def getThreads(self): return SurveyThread.objects.filter(parent_survey = self) threads = property(getThreads) def __unicode__(self): return self.vote and 'Good' or 'Bad' class Meta: get_latest_by = '-created' class SurveyThread(models.Model): survey = models.ManyToManyField(SurveyResult, related_name='parent_survey') email = models.EmailField(max_length=200) comment = models.TextField(blank=True, null=True) 

views.py:

 survey_list = SurveyResult.objects.filter(stay__guest__user=request.user) \ .select_related('stay', 'stay__guest') forms = {} for survey in survey_list: forms[survey] = SurveyThreadForm(data=request.POST or None, survey=survey) if forms[survey].is_valid(): instance = forms[survey].save() return redirect('.') 

forms.py

 class SurveyThreadForm(forms.Form): comment = forms.CharField(required=False, widget=forms.Textarea) def __init__(self, *args, **kwargs): self.survey = kwargs.pop('survey', None) if not self.survey: raise NotImplementedError("SurveyResult object is required at this moment") super(SurveyThreadForm, self).__init__(*args, **kwargs) self.fields['comment'].label = "Message to send to guest:" def save(self, commit=True): s = SurveyThread() s.survey = self.survey s.email = "test@test.com" s.comment = self.cleaned_data['comment'] if commit: s.save() return s 

错误信息:

 ValueError at / "<SurveyThread: SurveyThread object>" needs to have a value for field "surveythread" before this many-to-many relationship can be used. Request Method: POST Request URL: http://127.0.0.1:8000/ Django Version: 1.5.1 Exception Type: ValueError Exception Value: "<SurveyThread: SurveyThread object>" needs to have a value for field "surveythread" before this many-to-many relationship can be used. Exception Location: /Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/site-packages/django/db/models/fields/related.py in __init__, line 586 Python Executable: /Users/tlovett1/.virtualenvs/guestretain/bin/python Python Version: 2.7.2 Python Path: ['/Users/tlovett1/guestretain', '/Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg', '/Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/site-packages/pip-1.3.1-py2.7.egg', '/Users/tlovett1/.virtualenvs/guestretain/lib/python27.zip', '/Users/tlovett1/.virtualenvs/guestretain/lib/python2.7', '/Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/plat-darwin', '/Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/plat-mac', '/Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/plat-mac/lib-scriptpackages', '/Users/tlovett1/.virtualenvs/guestretain/Extras/lib/python', '/Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/lib-tk', '/Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/lib-old', '/Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/lib-dynload', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages', '/Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/site-packages', '/Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/site-packages/PIL'] Server time: Sun, 7 Jul 2013 10:22:55 -0500 

追溯:

 Traceback Switch to copy-and-paste view /Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/site-packages/django/core/handlers/base.py in get_response response = callback(request, *callback_args, **callback_kwargs) ... ▶ Local vars /Users/tlovett1/guestretain/retain/apps/profiles/utils.py in _wrapped_view return view_func(request, *args, **kwargs) ... ▶ Local vars /Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/site-packages/endless_pagination/decorators.py in decorated return view(request, *args, **kwargs) ... ▶ Local vars /Users/tlovett1/guestretain/retain/apps/dashboard/views.py in dashboard instance = forms[survey].save() ... ▶ Local vars /Users/tlovett1/guestretain/retain/apps/surveys/forms.py in save s.survey = self.survey ... ▶ Local vars /Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/site-packages/django/db/models/fields/related.py in __set__ manager = self.__get__(instance) ... ▶ Local vars /Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/site-packages/django/db/models/fields/related.py in __get__ through=self.field.rel.through, ... ▶ Local vars /Users/tlovett1/.virtualenvs/guestretain/lib/python2.7/site-packages/django/db/models/fields/related.py in __init__ (instance, source_field_name)) ... ▶ Local vars 

我是Django和Python的新手。 如果需要,我可以发布debugging跟踪或迁移文件,但我有一种感觉,这是一个简单的修复。 显然重点是我想为每个调查结果保存多个调查线程。

谢谢!

好吧,代码稍微凌乱,我相信你会更好地处理与ModelForms你的问题 。 对我来说,问题实际上是这样的:

 s.survey = self.survey 

因为s对象还没有被写入数据库,所以访问它的ManyToMany字段可能会产生问题。 如果你想从self复制相同的一套调查,你应该这样做迭代他们这样的:

如果这样会产生相同的错误,那么首先尝试执行s.save() ,然后复制项目:

 s.save() for item in self.survey: s.survey.add(item) 

你的代码很可能仍然是这样的:

 def save(self, commit=True): s = SurveyThread() # these fields aren't problematic s.email = "test@test.com" s.comment = self.cleaned_data['comment'] # you can add s.save() here to remove problems associated with object # not yet persisted # s.save() for item in self.survey: s.survey.add(item) if commit: s.save() return s 

我可以看到你有一个if commit:坚持对象,所以尽量容纳代码来使用它。 如果我的答案的第一个版本的工作,那么你会没事的s.save() ,如果第二个是谁的工作,那么你将不得不调整一些代码坚持commit值。

希望这可以帮助!

forms.py这部分代码中,您将SurveyThread对象上的survey字段设置为None ,但不能根据您的models.py将其设置为None

 def save(self, commit=True): s = SurveyThread() s.survey = None ### This is the problem s.email = "test@test.com" s.comment = self.cleaned_data['comment'] if commit: s.save() return s 

您必须SurveyResult survey设置为SurveyResult对象,然后才能保存它,或者在模型中将其设置为None

我想你想改变它说:

 s.survey = self.survey