是否有可能使用查询集改进Django中实例创建/删除的过程?

时间:2013-07-26 14:43:16

标签: django django-queryset

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

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

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/所以我有一个独特的项目列表,每个项目都有一个相关的电子邮件地址,对于几个项目可以是相同的。

1 个答案:

答案 0 :(得分: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也未定义