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.
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 = "[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.
Thanks!
To define a many-to-many relationship, use ManyToManyField . What follows are examples of operations that can be performed using the Python API facilities. You can't associate it with a Publication until it's been saved: >>> a1.
If you'd like to specify a custom primary key, specify primary_key=True on one of your fields. If Django sees you've explicitly set Field.primary_key , it won't add the automatic id column. Each model requires exactly one field to have primary_key=True (either explicitly declared or automatically added).
A model is a Python class that inherits from the Model class. The model class defines a new Kind of datastore entity and the properties the Kind is expected to take. The Kind name is defined by the instantiated class name that inherits from db.
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:
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:
If this yields the same error, then try to do s.save()
first and later copy the items:
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.
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With