更改表单中的主键会在DB中创建两个条目,一个具有旧主键,另一个具有新主键

时间:2012-12-07 10:12:10

标签: django django-models django-forms

代码:

型号:

class Machines(models.Model):
    name = models.CharField(max_length=100, verbose_name="hostname", help_text="Host name of the machine")
    ip_addr = models.CharField(max_length=50, primary_key=True, help_text="IP address of the machine")
.... have many other fields.

形式: 使用forms.ModelForm创建表单

查看:

def save(request):
if request.method == "POST":
        ip = request.POST.get("ip")
        machine = get_object_or_404(Machines, ip_addr=ip)
        form = MachineForm(instance=machine, data=request.POST)
        if form.is_valid():
            if form.has_changed():
                form.save()
                context = {"message": "Updated successfully"}
            else:   
                context = {"message": "No data to update"}
    return render_to_response("edit.html", context, context_instance=RequestContext(request))

如果我更改“name”字段,form.save()会正确更新当前对象。但是,如果我更改作为主键的“ip_addr”字段,form.save()将创建两个条目,其中一个旧主键,另一个使用新主键。

如果我们在MySQL中做同样的事情(BTW,我使用MySQL作为数据库)

update machines_table set ip_addr="10.1.1.1" where ip_addr="10.1.1.2";

工作正常,不会有任何重复的条目。

你能帮帮我吗。

1 个答案:

答案 0 :(得分:0)

您正在做的是更新私钥。 Django在这种情况下创建了新实例。这实际上是Django复制记录的方式。 INSERTUPDATE查询由ORM执行。

如果您将代码更改为:

class Machines(models.Model):
    …
    ip_addr = models.CharField(max_length=50, unique=True, …
    …

Django会正确解释您的编辑操作,因为主键不会改变。

下次使用django-debug-toolbar查看Django ORM执行的查询。