为什么我的表单被调用了两次?

1 投票
1 回答
1900 浏览
提问于 2025-04-17 15:32

当我尝试保存我的表单时,遇到了这个错误:

Exception Value:    

Cannot assign None: "TriggerService.user" does not allow null values.

Exception Location:     /usr/local/lib/python2.6/dist-packages/django/db/models/fields/related.py in __set__, line 362

这是我的模型、表单和视图的代码

models.py

class TriggerService(models.Model):
    """
        TriggerService
    """
    provider = models.ForeignKey(TriggerType, related_name='+', blank=True)
    consummer = models.ForeignKey(TriggerType, related_name='+', blank=True)
    description = models.CharField(max_length=200)
    user = models.ForeignKey(User)
    date_created = models.DateField(auto_now_add=True)

forms.py

class TriggerServiceForm(forms.ModelForm):
"""
    TriggerService Form
"""
    class Meta:
    """
        meta to add/override anything we need
    """
    model = TriggerService
    widgets = {
        'description':\
        TextInput(attrs={'placeholder':\
                         _('A description for your new service')}),
    }
    exclude = ('user',
               'date_created')

    provider = forms.ModelChoiceField(queryset=TriggerType.objects.all())
    consummer = forms.ModelChoiceField(queryset=TriggerType.objects.all())

    def save(self, user=None):
        myobject = super(TriggerServiceForm, self).save(commit=False)
        print "i am:"
        print user
        myobject.user = user
        myobject.save()

views.py

class TriggerServiceCreateView(CreateView):
    form_class = TriggerServiceForm
    template_name = "triggers/add_trigger.html"

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(TriggerServiceCreateView, self).dispatch(*args, **kwargs)

    def form_valid(self, form):
        self.object = form.save(user=self.request.user)
        return super(TriggerServiceCreateView, self).form_valid(form)

    def get_context_data(self, **kwargs):
        context = super(TriggerServiceCreateView, self).get_context_data(**kwargs)
        context['action'] = 'add_trigger'
        return context

正如你在我的表单中看到的,我添加了一个打印语句来跟踪发生了什么

奇怪的是,我的表单保存操作被执行了两次,为什么会这样?我该如何避免这种情况?

i am:
foxmask
i am:
None

1 个回答

3

这个:

def form_valid(self, form):
    # call form.save manually: creates "i am: foxmask"
    self.object = form.save(user=self.request.user)

    # Call parent form_valid(), CreateView.form_valid() ...
    # ... which also calls form.save() without user argument !!
    # So, it should create "i am: None" because the default value for 
    # the user argument of the save() method of your form is None.
    return super(TriggerServiceCreateView, self).form_valid(form)

还有,CreateView.form_valid() 会用 user=None 来调用 TriggerServiceForm.save()

所以在这里你不能使用 super(),因为它会直接调用父类的方法。

为什么不简单点呢:

from django import http

# ...

def form_valid(self, form):
    self.object = form.save(user=self.request.user)
    return http.HttpResponseRedirect(self.get_success_url())

撰写回答