Python Django 错误:在使用这种多对多关系之前,需要有字段“...”的值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17505935/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Django error: needs to have a value for field "..." before this many-to-many relationship can be used
提问by tlovett1
When saving a form I am getting this error: "" needs to have a value for field "surveythread" before this many-to-many relationship can be used.
保存表单时,我收到此错误:在使用这种多对多关系之前,“”需要为字段“surveythread”设置一个值。
Models.py:
模型.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:
视图.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
表格.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 = "[email protected]"
s.comment = self.cleaned_data['comment']
if commit:
s.save()
return s
Error Message:
错误信息:
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:
追溯:
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
I'm new to Django and Python. I can post the debug trace or migration file if needed, but I have a feeling it's a simple fix. Obviously the point is I want to save multiple survey thread for each survey result.
我是 Django 和 Python 的新手。如果需要,我可以发布调试跟踪或迁移文件,但我觉得这是一个简单的修复。显然,关键是我想为每个调查结果保存多个调查线程。
Thanks!
谢谢!
回答by Ben
In this part of the code in forms.py
, you're setting the survey
field on the SurveyThread
object to None
, yet it's not allowed to be None
according to your models.py
:
在 中的这部分代码中forms.py
,您将对象survey
上的字段设置SurveyThread
为None
,但不允许None
根据您的models.py
:
def save(self, commit=True):
s = SurveyThread()
s.survey = None ### This is the problem
s.email = "[email protected]"
s.comment = self.cleaned_data['comment']
if commit:
s.save()
return s
You have to set survey
to a SurveyResult
object before you can save it, or allow it to be None
in the model.
您必须先设置survey
一个SurveyResult
对象,然后才能保存它,或允许它出现None
在模型中。
I think you want to change it to say:
我想你想把它改成这样:
s.survey = self.survey
回答by Paulo Bu
Ok, the code is slightly messy, I'm sure you'll be better off tackling your problem with ModelForms
. Seems to me the problem actually is the line:
好的,代码有点乱,我相信你最好用ModelForms
. 在我看来,问题实际上是这一行:
s.survey = self.survey
because s
object hasn't been written to the database yet, so accessing it's survey
ManyToMany field can yield problems. If you want to copy the same set of surveys from self
to s
you should do it iterating over them like this:
因为s
对象还没有写入数据库,所以访问它的survey
ManyToMany 字段会产生问题。如果您想将同一组调查复制self
到s
您应该像这样迭代它们:
If this yields the same error, then try to do s.save()
first and later copy the items:
如果这会产生相同的错误,请尝试先执行,然后再s.save()
复制项目:
s.save()
for item in self.survey:
s.survey.add(item)
Your code is likely to remain like this:
您的代码可能会保持如下:
def save(self, commit=True):
s = SurveyThread()
# these fields aren't problematic
s.email = "[email protected]"
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
I can see you have a if commit:
to persist the object, so try to accommodate the code to make use of it. If the first version of my answer worked then you'll be fine with the s.save()
at the end, if the second is the one who worked, then you'll have to adjust the code a little to stick to the commit
value.
我可以看到您有一个if commit:
持久化对象,因此请尝试容纳代码以使用它。如果我的答案的第一个版本有效,那么最后你会没事的s.save()
,如果第二个是有效的,那么你必须稍微调整代码以坚持该commit
值。
Hope this helps!
希望这可以帮助!