Django更新而不是插入新记录

时间:2012-02-27 22:23:47

标签: python django django-models django-forms

我对Django 1.3有一个奇怪的问题。当我尝试使用ActivityForm添加新的Activity时,即使我显式创建一个不是Id的新Activity对象,Activity也经常更新。

此外,当我的ActivityForm类的 init 具有显式trip_id参数时,UI会显示“选择有效选项。该选项不是可用选项之一”。对于字段位置(即使显示的选择有效)。但是,如果我将它设为可选参数并从kwargs中弹出它,我就不会看到这个问题。

有人可以看看下面的代码,看看我做错了什么?

forms.py

class DestinationMultipleChoiceField(ModelMultipleChoiceField):
    def label_from_instance(self, obj):
        return obj.city_name

class ActivityForm(forms.Form):
    description = forms.CharField(max_length=100, required=True)
    location = DestinationChoiceField(queryset = Visit.objects.none(), empty_label=None, required=True)

    def __init__(self, trip_id = None, *args, **kwargs):
        super(ActivityForm, self).__init__(*args, **kwargs)
        if trip_id is not None:
            self.fields['location'].queryset = Visit.objects.filter(trip=trip_id).all().select_related('destination')

    # A new Activity() is created if nothing is provided
    def save(self, activity = Activity()):
        if not self.is_valid():
            raise forms.ValidationError('ActivityForm was not validated first before trying to call save().')

        activity.visit = self.cleaned_data['location']
        activity.description = self.cleaned_data['description']
        activity.added_by = User.objects.get(pk=1)
        activity.save()

views.py

def add_activity(request, trip_id = None, template_name = 'edit-form.html'):
    if request.POST:
        form = ActivityForm(trip_id, request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('views.list_trip'))
    else:
        form = ActivityForm(trip_id)

    return render_to_response(template_name, {
        'page_title': 'Add',
        'form': form,
    }, context_instance=RequestContext(request))

2 个答案:

答案 0 :(得分:6)

看看这一行:

def save(self, activity = Activity()):

在Python中,默认参数被评估一次;因此,当save方法第一次调用 时,将创建一个新的Activity,但后续调用将使用 {{1 }}

Activity更改为以下内容:

save

然后,每次调用都会创建一个新的def save(self, activity=None): if activity is None: activity = Activity() # Rest of the method (如果没有提供参数)。

答案 1 :(得分:2)

模型实例是可变的。因此,它们永远不会被用作方法的默认参数,就像在save中一样。你有没有在任何文档或例子中看到过这个原因。

正如本网站上的许多其他问题所述,默认参数是根据定义而不是执行来评估的。因此,每次调用没有活动参数的save都将使用最初定义的相同的活动。

但是,我不明白为什么你没有使用ModelForm,它在任何情况下都会为你做大部分工作。