2013-04-10 3 views
2

Vu le code suivant:Obtenez premier objet de Django QuerySet

randomItemQS = Item.objects.filter().exclude(id__in=[o.id for o in collection]).order_by('?') 
randomItem = randomItemQS[:1] 
calculation = randomItem.method()/constant 

Comment puis-je faire en sorte que randomItem est un Item et non un QuerySet?

Si je cours le code de manage.py shell, alors j'obtiens le résultat attendu. Toutefois, l'exécution de ce code à partir d'une vue entraîne l'attribut AttributeError 'QuerySet' object has no attribute 'method' et indique que l'erreur se produit sur la dernière ligne.

Qu'est-ce qui me manque?

EDIT: Désolé, je devrais être plus précis - J'ai cela fonctionne très bien dans le shell, mais cela ne fonctionne pas dans la vue. Qu'est-ce qui serait différent?

+0

'randomItemQS [0]' – catherine

+0

Voir la réponse de Pavel ci-dessous. –

+1

Non lié, mais si 'collection' est lui-même un jeu de requête, vous devez simplement faire' exclure (id__in = collection) ', qui utilise une sous-requête et supprime le besoin d'évaluer la collection séparément. –

Répondre

2

Juste indexer, tranchage ajoute une requête limite à la QS sans l'exécuter:

randomItem = randomItemQS[0] 
+0

Cela modifie le message d'erreur 'IndexError: liste index hors de portée' pour une raison quelconque. Je ne sais pas pourquoi ... le QuerySet retourne plus de 150 objets. –

+0

Etes-vous sûr? 'print randomItemQS.count()'. –

+0

J'étais un peu hors ... 145. –

1

Vous pouvez faire ceci:

randomItem=None 
randomItemQS = Item.objects.filter().exclude(id__in=[o.id for o in collection]).order_by('?')[:1] 
if randomItemQS: 
    randomItem = randomItemQS[0] 
    calculation = randomItem.method()/constant 
0

Comme la question portait sur la différence entre une vue et une fenêtre shell, la réponse correcte est de convertir les paramètres passés à la vue en un entier pour s'assurer que la requête renvoie les objets comme prévu.

D'autres réponses ont été remises en cause comme elles sont valides. Merci.