检查元素是否存在

时间:2009-07-29 16:12:11

标签: python django performance

我试图找出Django模型中的元素是否存在。我认为这应该很容易,但在Django文档的Making queries部分找不到任何优雅的方法。

我遇到的问题是我在目录中有数千个屏幕截图,需要检查它们是否存在于应该存储它们的数据库中。所以我正在迭代文件名,并希望看到每个文件名是否存在相应的元素。有一个名为屏幕截图的模型,我能想到的唯一方法是

filenames = os.listdir(settings.SCREENSHOTS_ON_DISC)
for filename in filenames:
    exists = Screenshot.objects.filter(filename=filename)
    if exists:
        ...

有更好/更快的方法吗?请注意,屏幕截图可以在数据库中多次出现(因此我没有使用.get)。

3 个答案:

答案 0 :(得分:2)

如果您的Screenshot模型具有很多属性,那么您展示的代码就是根据您的特定需求进行不必要的工作。例如,您可以执行以下操作:

files_in_db = Screenshot.objects.values_list('filename', flat=True).distinct()

将为您提供数据库中所有文件名的列表,并生成SQL以仅获取文件名。它不会尝试创建和填充Screenshot对象。如果你有

files_on_disc = os.listdir(settings.SCREENSHOTS_ON_DISC)

然后你可以迭代一个列表寻找另一个列表中的成员资格,或者将一个或两个列表组成集合以查找普通成员等。

答案 1 :(得分:1)

你可以尝试:

Screenshot.objects.filter(filename__in = filenames)

这将为您提供所有屏幕截图的列表。您可以比较两个列表,看看两者之间不存在什么。这应该让你开始,但你可能想要调整性能/使用的查询。

答案 2 :(得分:1)

此查询可以获取数据库和文件系统中的所有文件:

discfiles = os.listdir(settings.SCREENSHOTS_ON_DISC)

filenames = (Screenshot.objects.filter(filename__in=discfiles)
                               .values_list('filename', flat=True)
                               .order_by('filename')
                               .distinct())

请注意order_by。如果您在模型定义中指定了排序,则使用distinct可能无法返回您期望的顺序。这在此处记录:

所以明确排序,然后执行查询。