Django更新,而不是插入新记录

问题描述:

我有一个奇怪的问题与Django 1.3。当我尝试使用ActivityForm添加一个新的Activity时,即使我使用非Id显式创建一个新的Activity对象,该活动也会经常更新。Django更新,而不是插入新记录

另外,当我的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)) 

看这个行:

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

在Python,默认参数进行评估一次;因此,当save方法被称为第一次时,将创建一个新的Activity,但随后的调用将使用Activity

变化save到这样的事情:

def save(self, activity=None): 
    if activity is None: 
     activity = Activity() 
    # Rest of the method 

然后,新Activity将在每次调用创建(如果没有作为参数提供)。

模型实例是可变的。因此,他们应该使用从不使用作为方法的默认参数,就像您在save中所做的那样。你有没有在任何文档或例子中看到过这个原因。

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

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

+0

我没有使用ModelForm,因为我需要触摸多个实体。 – Martin 2012-02-27 22:32:39