2009-07-29 241 views
0

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

我现在的问题是,我在一个目录中有成千上万的屏幕截图,需要检查它们是否在应该存储它们的数据库中。所以我正在遍历文件名,并希望看到他们每个人是否存在相应的元素。有一个叫做屏幕截图的模型,我能想到的唯一方法是

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

有没有更好/更快的方法来做到这一点?请注意,截图可以在数据库中多次(因此我没有使用.get)。

回答

2

如果您的Screenshot模型具有很多属性,那么您显示的代码为您的特定需求做了不必要的工作。例如,你可以这样做:

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

,这将给你数据库中的所有文件名列表,并生成SQL只获取文件名。它不会尝试创建并填充屏幕截图对象。如果你有

files_on_disc = os.listdir(settings.SCREENSHOTS_ON_DISC) 

,那么你可以在一个列表迭代中的其他找会员,或使一个或两个列表成为集来找到共同的成员等

1

你可以尝试:

Screenshot.objects.filter(filename__in = filenames) 

这将会给你所有你确实有截图的列表。你可以比较两个列表,看看两者之间不存在什么。这应该让你开始,但你可能想调整查询的性能/使用。

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可能不会返回您所期望的。这是记录在这里:

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