Подтвердить что ты не робот

Ошибка 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 = "[email protected]"
        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:

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. Я могу опубликовать трассировку отладки или файл миграции, если это необходимо, но у меня есть ощущение, что это простое исправление. Очевидно, что я хочу сохранить несколько потоков опроса для каждого результата опроса.

Спасибо!

4b9b3361

Ответ 1

Хорошо, код немного грязный, я уверен, что вам будет лучше решить вашу проблему с помощью ModelForms. Кажется, проблема на самом деле - это строка:

s.survey = self.survey

поскольку объект s еще не был записан в базу данных, поэтому доступ к нему survey Поле ManyToMany может привести к проблемам. Если вы хотите скопировать тот же набор опросов от self до s, вы должны сделать это, итерации по ним следующим образом:

Если это дает ту же ошибку, попробуйте сделать 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 = "[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

Я вижу, что у вас есть if commit:, чтобы сохранить объект, поэтому постарайтесь использовать код, чтобы использовать его. Если первая версия моего ответа сработала, то с тегом s.save() все будет в порядке, если второе - это тот, кто работал, тогда вам придется немного изменить код, чтобы придерживаться commit значение.

Надеюсь, это поможет!

Ответ 2

В этой части кода в 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

Вы должны установить survey в объект SurveyResult, прежде чем сможете сохранить его, или разрешить ему None в модели.

Я думаю, вы хотите изменить его, чтобы сказать:

s.survey = self.survey