model.AutoField - form.save()创建新记录(INSERT)而不是更新现有记录

时间:2011-10-19 10:24:52

标签: django django-models django-forms django-database

情境:拥有包含一些数据的现有mysql数据库。对于这个例子,我只使用两个字段; id 主题 id 使用* auto_increment *选项定义为Integer,而 subject 只是普通的varchar。代码:

模型

class AList(models.Model):
    id=models.AutoField(primary_key=True, db_column='ID')
    subject=models.CharField(max_length=200, db_column='SUBJECT')
    class Meta:
        db_table = u'alist'

表格

class AForm(ModelForm):
    class Meta:
        model=AList

查看

def alistForm(request,a_id=None):
    if a_id:
        a=AList.objects.get(id=a_id)
        form=AForm(instance=a)
    else:
        form=AForm(request.POST or None)
    return render_to_response('aform.html',{'form':form},context_instance=RequestContext(request)

def alistPost(request):
    form=AForm(request.POST or None)
    if form.is_valid():
        form.save()

问题描述: 当表单将新数据发送到alistPost函数时, form.save()会按原样插入新记录。但是当我编辑一个已经存在的记录时,它也会作为一个新记录插入......并且不会像应该的那样进行更新。

尝试将ID从 AutoField 更改为 IntegerField 会更改行为:修改记录会使 form.save()修改现有的一个,在尝试插入新记录时失败,因为它没有id。

问题: 我是否需要手动从数据库中获取新的ID值并强制Django将其用于此新记录,或者是否有办法让Django自动确定它是否应该使用INSERT或UPDATE?

3 个答案:

答案 0 :(得分:4)

龙骑在正确的轨道上,但你的评论是有效的。更好的模式是这样的:

if a_id:
    a = AList.objects.get(id=a_id)
else:
    a = AList()
if request.POST:
    form = AForm(request.POST, instance=a)
    ...
else:
    form = AForm(instance=a)

答案 1 :(得分:1)

这就是我所做的:

def someView(request,id=None):
   instance = form = None

   ...
      ...
   elif request.method == 'POST':

        if id != None:
            instance = SomeClass.objects.get(id=id)
            form = AForm(request.POST,instance=instance)
        else:
            form = AForm(request.POST) 

        if form.is_valid():

           instance = form.save()
           if not id:
               return redirect('edit',id=instance.id)
        else
            ...
        ...

网址:

url(r'^addedit/$', 'som.views.someView', name='edit'),
url(r'^addedit/(?P<id>.*)/$', 'som.views.someView', name='edit'),

所以在/ addedit /创建对象后,用户被重定向到/ addedit / 1234 /

答案 2 :(得分:0)

问题是您在单独的函数中执行POST,其中不向表单提供 instance参数。

尝试将函数合并为如下所示:

def alistForm(request, pk)
    alist = get_object_or_404(AList, pk=pk)
    form = AFrom(request.POST or None, instance=alist)
    if request.method == 'POST':
        if form.is_valid():
            form.save()
    ...