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