清理表单并访问self.instance.user时,Django RelatedObjectDoesNotExist存在

时间:2018-11-03 07:15:00

标签: django django-models django-forms

我无法弄清楚为什么在覆盖表格的clean方法时尝试访问self.instance.user时会得到RelatedObjectDoesNotExist。这并非每次都会发生,并且几乎是随机的,这就是为什么它给我带来很多麻烦。请参阅下面的表格和模型

forms.py

class UserSurveyQueueForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        super().__init__(*args, **kwargs)
        self.fields['queue'].queryset = Employees.objects.all()
        self.fields['queue'].required = False

    def clean(self):
        cleaned_data = self.cleaned_data
        users_added = cleaned_data.get('queue')
        if users_added:
            for user in users_added:
                if user == self.instance.user:
                    raise forms.ValidationError("Yikes, you can't add {} to {}'s queue!".format(
                        self.instance.user.employee.first_name, self.instance.user.employee.first_name
                    ))

                last_created = UserNPS.objects.filter(user=user.employee, reporter=self.instance.user.employee).values(
                'created_at').last()
                if last_created:
                    timedelta = (timezone.now() - last_created['created_at']).days
                    if timedelta <= settings.DAYS_BETWEEN_SURVEYS:
                        raise forms.ValidationError("You have recently filled out a survey for {} {}, please wait {} days before doing so again!".format(
                            user.employee.first_name, user.employee.last_name, settings.DAYS_BETWEEN_SURVEYS - timedelta))


    class Meta:
        model = UserSurveyQueue
        fields = ('queue',)
        widgets = {
            'queue': autocomplete.ModelSelect2Multiple(
                url='user-autocomplete',
                attrs={
                    'data-placeholder': 'Search by name, username, email, department, office, or team',
                }
            ),
        }

models.py

class UserSurveyQueue(models.Model):
    user = models.OneToOneField(
        Employees,
        on_delete=models.CASCADE
    )
    queue = models.ManyToManyField(
        Employees,
        blank=True,
        related_name='survey_queue',
    )

    class Meta:
        verbose_name = ('Survey Queue')
        verbose_name_plural = ('Survey Queues')

    def current_queue(self):
        return ", ".join([str(q.employee.username) for q in self.queue.all()])

    def __str__(self):
        return self.user.employee.username

错误:

File "forms.py" in clean
  62.                 if user == self.instance.user:

File "lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py" in __get__
  175.                 "%s has no %s." % (self.field.model.__name__, self.field.name)
django.db.models.fields.related_descriptors.RelatedObjectDoesNotExist: UserSurveyQueue has no user.

1 个答案:

答案 0 :(得分:1)

在创建对象时会发生此错误,而在更新对象时不会发生。创建它时,请勿使用self.instance.user,因为它尚不存在。

__init__中弹出表单时,还应将用户绑定到表单。您应该编写self.user = kwargs.pop('user'),然后在self.user类中使用UserSurveyQueueForm访问它。