2009-07-29 12 views
0

J'essaie de savoir si un élément existe dans un modèle Django. Je pense que cela devrait être très facile à faire, mais n'a pas trouvé de manière élégante dans la section Making queries de la documentation de Django. Le problème que j'ai est que j'ai des milliers de captures d'écran dans un répertoire et que j'ai besoin de vérifier si elles sont dans la base de données qui est censée les stocker. Donc je suis en train d'itérer sur les noms de fichiers et je veux voir pour chacun d'eux si un élément correspondant existe. Ayant un modèle appelé Capture d'écran, la seule façon que je pourrais trouver estVérifier si un élément existe

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

Y at-il une façon plus agréable/plus rapide de faire cela? Notez qu'une capture d'écran peut être dans la base de données plus d'une fois (donc je n'ai pas utilisé .get).

Répondre

2

Si votre modèle Screenshot a beaucoup d'attributs, alors le code que vous avez montré fait un travail inutile pour votre besoin spécifique. Par exemple, vous pouvez faire quelque chose comme ceci:

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

qui vous donnera une liste de tous les noms de fichiers dans la base de données et générer des requêtes SQL pour aller chercher uniquement les noms de fichiers. Il n'essaiera pas de créer et de peupler les objets Screenshot. Si vous avez

files_on_disc = os.listdir(settings.SCREENSHOTS_ON_DISC) 

vous pouvez itérer sur une liste à la recherche d'appartenance à l'autre, ou faire une ou deux listes en ensembles pour trouver des membres communs, etc.

1

Vous pouvez essayer:

Screenshot.objects.filter(filename__in = filenames) 

Cela vous donnera une liste de toutes les captures d'écran que vous avez. Vous pourriez comparer les deux listes et voir ce qui n'existe pas entre les deux. Cela devrait vous aider à démarrer, mais vous voudrez peut-être modifier la requête pour la performance/utilisation.

1

Cette requête vous obtient tous les fichiers sont dans votre base de données et système de fichiers:

discfiles = os.listdir(settings.SCREENSHOTS_ON_DISC) 

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

Notez le order_by. Si vous avez spécifié une commande dans votre définition de modèle, l'utilisation de distinct risque de ne pas renvoyer ce que vous attendiez. Ceci est documenté ici:

donc faire l'ordre explicite, puis exécuter la requête.

Questions connexes