Désolé si la question semble bizarre. Je me demande simplement s'il est possible de créer un nouveau queryset alors que j'ai déjà un queryset.
Par exemple ici ...
everyone = User.objects.filter(is_active=True) # this would of course return all users that's active
not_deleted = User.objects.filter(is_active=True, is_deleted=False) # return user that's active and not deleted
is_deleted = User.objects.filter(is_active=True, is_deleted=True) # return user that's active and is already deleted
Quelle est ma question ... pour not_deleted
et is_deleted
dont les deux sont actifs est vrai avec est identique à everyone
existe-t-il un moyen possible d'utiliser everyone
et de filtrer en quelque sorte is_deleted=True
ou is_deleted=False
? Alors je pense que l'interrogation serait plus rapide et meilleure si c'était possible, n'est-ce pas?
Les trois variables everyone
, not_deleted
et is_deleted
seront alors utilisées pour autre chose.
J'espère que ma question est claire.
Merci d'avance.
Oui, vous pouvez réutiliser des ensembles de requêtes existants.
everyone = User.objects.filter(is_active=True)
active_not_deleted = everyone.filter(is_deleted=False)
active_is_deleted = everyone.filter(is_deleted=True)
Cela ne permet pas d'accélérer les choses, mais ce bloc de code n'exécutera même pas de requête sur la base de données, car les QuangoSets de Django sont évalués paresseusement. Ce que je veux dire, c'est qu'il n'enverra pas la requête à la base de données tant que vous n'avez pas réellement besoin des valeurs. Voici un exemple qui va parler à la base de données.
everyone = User.objects.filter(is_active=True) # Building SQL...
active_not_deleted = everyone.filter(is_deleted=False) # Building SQL...
active_is_deleted = everyone.filter(is_deleted=True) # Building SQL...
# Example of the whole queryset being evaluated
for user in everyone:
# This will execute the query against the database to return the list of users
# i.e. "select * from user where is_active is True;"
print(user)
# Example of using iterator to evaluate one object at a time from the queryset.
for user in active_not_deleted.iterator():
# This will execute the query for each result, so it doesn't
# load everything at once and it doesn't cache the results.
# "select * from user where is_active is True and is_deleted is False limit 1 offset 0;"
# The offset is incremented on each loop and another query is sent to retrieve the next user in the list.
print(user)
Recommander la lecture:
En complément de cette réponse, vous pouvez effectuer une requête unique, puis filtrer en Python si vous le souhaitez vraiment. Notez que vous ne pouvez pas effectuer de filtrage ultérieur sur les listes car elles ne sont pas des QuerySets.
everyone = User.objects.filter(is_active=True)
active_not_deleted = list(filter(lambda user: user.is_deleted is False), list(everyone))
active_is_deleted = list(filter(lambda user: user.is_deleted is True), list(everyone))
Dans ce dernier exemple, everyone
est un queryset et active_not_deleted
et active_is_deleted
sont des listes Python d'objets User. Le __set de requête everyone
ne sera évalué qu'une seule fois lors du premier appel list(everyone)
, puis les résultats seront mis en cache.
Vous pouvez filtrer le nombre de requêtes souhaité autant de fois que vous le souhaitez, car filter()
renvoie un nouveau jeu de requêtes. Ainsi, après filtrage, vous obtenez un filtre filtré et vous pouvez filtrer ou orderby et une autre méthode qui renvoie de nouveaux ensembles de requêtes
Donc, vous pouvez faire ceci:
active = User.objects.filter(active=True)
deleted = active.filter(is_deleted=True)
not_deleted = active.filter(is_deleted=False)
Tout cela parce que User.objects
- est Queryset et User.objects.filter
retournent également Queryset.
Le mieux que vous puissiez faire est:
active_users = User.objects.filter(active=True)
not_deleted = active_users.filter(is_deleted=False)
deleted = active_users.filter(is_deleted=True)
Donc, la réponse à votre question peut être oui, si je comprends bien.