0

所以我有一个唯一学生的列表(学生是 LDAP 数据库中的 primary_key,每个都有一个关联的老师,对于几个学生来说可以是相同的。

每个老师的学生的编辑表单中有一个框,用户可以在其中添加/删除学生,然后使用以下功能更新数据库。我目前的功能如下。(teacher是与编辑页面表单关联的老师,是已提交并传递给此函数updated_list的 s 姓名列表)pupil

def update_pupils(teacher, updated_list):

    old_pupils = Pupil.objects.filter(teacher=teacher)
    for pupils in old_pupils:
        if pupil.name not in updated_list:
            pupil.delete()
        else:
            updated_list.remove(pupil.name)
    for pupil in updated_list:
        if not Pupil.objects.filter(name=name):
            new_pupil = pupil(name=name, teacher=teacher)
            new_pupil.save()

如您所见,该函数基本上找到了老师的旧学生列表,查看这些,如果实例不在我们的新 updated_list 中,则将其从数据库中删除。然后我们删除那些从 updated_list 中删除的(或者至少是他们的名字)......这意味着剩下的是新创建的,然后我们迭代并保存。

现在理想情况下,如果有意义的话,我想尽可能少地访问数据库。那么我可以执行以下任何操作吗?

在最初的迭代中,我是否可以简单地将这些学生标记为删除,并可能在以后一起删除和保存?我知道我可以批量删除项目,但我可以以某种方式标记我想要删除的项目,而无需访问我知道如果删除数量会很高的话可能会很昂贵的数据库......然后删除很多一次?

在第二次迭代中,是否可以创建各种实例,然后一次性保存它们?同样,我在 Django 1.4 中看到您可以使用bulk_create,但是您如何保存这些?另外,我实际上使用的是 Django 1.3 :(...

我有点假设上述步骤实际上有助于函数的性能?...但如果不是这样,请告诉我。

我当然一直在阅读这个https://docs.djangoproject.com/en/1.3/ref/models/querysets/所以我有一个独特项目的列表,每个项目都有一个关联的电子邮件地址,这可以是相同的几个项目。

4

1 回答 1

1

首先,在这一行

if not Pupil.objects.filter(name=name):

看起来name变量是未定义的,不是吗?

然后这是我认为您的代码的快捷方式:

def update_pupils(teacher, updated_list):
    # Step 1 : delete
    Pupil.objects.filter(teacher=teacher).exclude(name__in=updated_list).delete() # delete all the not updated objects for this teacher

    # Step 2 : update
      # either
    for name in updated_list:
        Pupil.objects.update_or_create(name=name, defaults={teacher:teacher}) # for updated objects, if an object of this name exists, update its teacher, else create a new object with the name from updated_list and the input teacher
      # or (but I'm not sure this one will work)
    Pupil.objects.update_or_create(name__in=updated_list, defaults={teacher:teacher})

另一种解决方案,如果您的 Pupil 对象只有这两个属性并且没有被另一个关系中的外键引用,则删除该教师的所有“Pupil”实例,然后使用 bulk_create.. 它只允许 2 次访问到数据库,但它很丑

编辑:在第一个循环中,pupil也是未定义的

于 2013-07-26T16:20:09.237 回答