2
votes

Comment obtenir l'équivalent de python [: -1] dans django ORM?

J'écris une application Django où je souhaite récupérer tous les éléments mais en dernier à partir d'une requête. Ma requête va comme ceci:

objects = Model.objects.filter(name='alpha').order_by('rank')[:-1]

mais elle renvoie une erreur:

Erreur d'assertion: l'indexation négative n'est pas prise en charge. Toute idée où je suis ça va mal?

Toutes les suggestions seront appréciées.


3 commentaires

La plupart des dialectes SQL (sinon tous) ne prennent pas en charge la sélection de tous les enregistrements sauf le dernier, du moins pas sans quelques "astuces". Cela étant dit, un enregistrement ne représente généralement pas vraiment beaucoup de surcharge, vous pouvez donc d'abord le convertir en une liste, comme list (Model.objects.filter (..). Order_by (..)) [: - 1 ] .


le dernier élément a-t-il une caractéristique distinctive?


Copie possible de comment pour obtenir le premier élément et le dernier élément en utilisant django, Location.objects.all ()


4 Réponses :


1
votes

< EDITED

Django ne prend pas en charge l'indexation négative sur les QuerySets. Veuillez lire https://code.djangoproject.com/ticket/13089 pour plus d'informations. < / p>

La manière rapide et "sale" de le faire est de convertir le Queryset sous forme de liste, puis d'utiliser l'indexation négative.

objets = liste (Model.objects.filter (name = 'alpha'). order_by ('rank')) [: - 1]

Veuillez noter que la variable des objets n'est plus un ensemble de requêtes mais une liste.

Cependant, je recommanderais d'utiliser .exclude () .

Si vous souhaitez utiliser la méthode .exclude (), que je recommande, je voudrais vous demander de lire la solution que @RaydelMiranda a écrite ci-dessous.


5 commentaires

Il existe la dernière méthode de QuerySets. Pas besoin de convertir le résultat en liste. En outre, essayez de convertir qs en liste tout comme la dernière ressource, il y a un coût en termes de performances.


@RaydelMiranda Je sais que ce n'est pas la meilleure solution, mais j'ai seulement montré qu'il était possible de supprimer le dernier élément de la manière dont il voulait l'utiliser. Si vous continuez à lire, vous verrez que je recommande une méthode différente pour exclure ou supprimer l'objet qu'il ne souhaite pas voir dans son QuerySet.


La façon dont il voulait l'utiliser, n'est pas possible, Django ne supporte pas les tranches sur -1 . Vous devez d'abord convertir un jeu de requêtes en liste, et dans l'autre partie de la réponse, vous montrez comment exclure un objet, mais pas le dernier après avoir trié par rang comme il le souhaitait.


Ah, je vois ce que vous entendez par vous montrez comment exclure un objet, mais pas le dernier après avoir ordonné par rang comme il le voulait. . Entièrement d'accord avec vous. Je modifierai ma réponse.


Bien, c'est maintenant une réponse plus utile, +1.



2
votes

Vous pouvez utiliser QuerySet.last () pour obtenir le dernier et utiliser son identifiant pour l'exclure des résultats.

objects = Model.objects.annotate(
    mini_rank=Min('rank'),         # Annotate each object with the minimum known rank
).exclude(
    mini_rank=F('rank')            # Exclude all objects ranked with the minimum value found   
)

Une requête pour exclure du résultat tous les objets classés avec la valeur minimale trouvée dans DB:

objects = Model.objects.filter(name='alpha').order_by('rank')
last = objects.last()
objects = objects.exclude(pk=last.pk)


0 commentaires

0
votes

L'indexation négative n'est pas autorisée dans Django. Cependant, vous pouvez utiliser l'indexation négative dans la fonction order_by et prendre le premier ou n'importe quel nombre d'objets dans l'ordre. Vous pouvez faire quelque chose comme ceci:

objects = Model.objects.filter(name='alpha').order_by('-rank')[1:]

Ici n suggère le nombre d'objets dont vous aurez besoin. Dans votre cas, ce serait:

objects = Model.objects.filter(name='alpha').order_by('-rank')[n:]


0 commentaires

0
votes
    query=model.objects.filter(user=request.user)
    if query.exists():
        query=query.last()

2 commentaires

Vous voudrez peut-être ajouter du texte avec votre réponse; pas seulement du code.


Bonjour, bienvenue dans Stack Overflow! Lorsque vous répondez à une question, vous devez inclure une sorte d'explication, comme ce que l'auteur a fait de mal et ce que vous avez fait pour y remédier. Je vous dis cela parce que votre réponse a été signalée comme étant de mauvaise qualité et est actuellement en cours de révision. Vous pouvez modifier votre réponse en cliquant sur le bouton "Modifier".