2012-03-15 3 views
5

Est-ce que je peux ou dois faire cela dans une vue?Modification d'un objet QuerySet à la volée dans Django

a = SomeTable.objects.all() 
for r in a: 
    if r.some_column == 'foo': 
     r.some_column = 'bar' 

Il a travaillé comme un champion, mais j'ai essayé quelque chose de semblable ailleurs et je recevais des résultats étranges, ce qui implique que les objets QuerySet n'aiment pas à la légère. Et, je n'ai rien vu dans les docs, bon ou mauvais pour ce genre de truc.

Je sais qu'il y a d'autres façons de le faire, mais je veux spécifiquement savoir si c'est une mauvaise idée, pourquoi c'est mauvais, et si c'est vraiment mauvais, quelle est la 'meilleure' façon django/pythonique changer les valeurs à la volée serait.

Répondre

6

C'est très bien tant que vous ne faites rien plus tard qui entraînera la réévaluation du jeu de requête - par exemple, le trancher. Cela fera une autre requête à la base de données, et tous vos objets modifiés seront remplacés par des nouveaux.

Une façon de vous protéger contre ce serait de convertir à une première liste:

a = list(SomeTable.objects.all()) 

De cette façon, plus tranchage etc ne causera pas un nouvel appel db, et toute modification sera conservée.

+0

Merci, Daniel. Votre exemple est exactement ce que je voulais dire quand j'ai dit: «Je sais qu'il y a d'autres moyens de le faire», et j'apprécie également votre clarification. Oh, et votre exemple de prendre une tranche est exactement ce qui causait les résultats étranges que j'ai mentionnés. Je suis un peu gêné de ne pas l'avoir compris, et je suis content que vous l'ayez signalé. À votre santé! – proffrink

0

Yup. Voir docs here

SomeTable.objects.filter(some_column='foo').update(some_column='bar') 

j'irais avec le langage de Django. Il exécute le SQL avec une seule instruction avec 'where' et 'update' plutôt que d'envoyer plusieurs instructions SQL comme le ferait votre code. Cela fait gagner du temps. Vérifiez avec 'connection' de Django pour tester l'heure SQL.

+4

Merci, et je m'excuse si je n'étais pas clair, mais je ne suis pas intéressé par la mise à jour de la base de données, il suffit de modifier la sortie à des fins d'affichage. – proffrink