我试图找出Django模型中的元素是否存在。我认为这应该很容易,但在Django文档的Making queries部分找不到任何优雅的方法。
我遇到的问题是我在目录中有数千个屏幕截图,需要检查它们是否存在于应该存储它们的数据库中。所以我正在迭代文件名,并希望看到每个文件名是否存在相应的元素。有一个名为屏幕截图的模型,我能想到的唯一方法是
filenames = os.listdir(settings.SCREENSHOTS_ON_DISC)
for filename in filenames:
exists = Screenshot.objects.filter(filename=filename)
if exists:
...
有更好/更快的方法吗?请注意,屏幕截图可以在数据库中多次出现(因此我没有使用.get)。
答案 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
可能无法返回您期望的顺序。这在此处记录:
所以明确排序,然后执行查询。