Hoe voeg ik een modelinstantie toe aan een django-queryset?

Het lijkt erop dat een django-queryset zich op de een of andere manier gedraagt ​​als een pythonlijst.

Maar het ondersteunt de .append()-methode van list niet, zoals ik weet.

Wat ik wil doen is als volgt:

from my_django_app.models import MyModel
queryset = MyModel.objects.none()
queryset.append(MyModel.objects.first())      ## no list's .append() method!

Is er een manier om een ​​modelinstantie aan een bestaande queryset toe te voegen?


Antwoord 1, autoriteit 100%

U kunt ook de operator |gebruiken om een ​​unie te maken:

queryset = MyModel.objects.none()
instance = MyModel.objects.first()
queryset |= MyModel.objects.filter(pk=instance.pk)

Maar wees gewaarschuwd dat dit verschillende zoekopdrachten zal genereren, afhankelijk van het aantal items dat u op deze manier toevoegt, waardoor het cachen van gecompileerde zoekopdrachten inefficiënt wordt.


Antwoord 2, autoriteit 53%

Nee. Een queryset is een weergave van een query– vandaar de naam – niet een willekeurige verzameling instanties.

Als je echt een echte queryset nodig hebt in plaats van een lijst, kun je proberen de ID’s van de objecten die je nodig hebt te verzamelen en vervolgens de objecten te verkrijgen via een __in-query:

list_of_ids = []
list_of_ids.append(my_id)
...
queryset = MyModel.objects.filter(id__in=list_of_ids)

Dit is echter niet erg efficiënt.


Antwoord 3, autoriteit 21%

Dit kan met behulp van union. Na dit te hebben gedaan, kan het type resultaat worden gezien als <class 'django.db.models.query.QuerySet'>. Er kunnen dus twee querysets worden gecombineerd. Laten we een voorbeeld bekijken.

query1 = User.objects.filter(is_active=True)
query2 = User.objects.filter(is_active=False)
combined_query = query1.union(query2)
print (type(combined_query))

Het bovenstaande programma drukt het resultaat af zoals hieronder, om te bevestigen dat het een queryset is

<class 'django.db.models.query.QuerySet'>

Dus eigenlijk voert Django de onderstaande query uit voor union.

(SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."is_active" = True) 
UNION 
(SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."is_active" = False)

Dit betekent ook dat er een fout optreedt (django.db.utils.ProgrammingError: each UNION query must have the same number of columns) als samenvoeging wordt geprobeerd met twee verschillende tabellen.


Antwoord 4, autoriteit 12%

Queryset is geen list

Dus

to_list = queryset.values()

Om queryset

te combineren

from itertools import chain
result_queryset = list(chain(queryset1, queryset2))

of

querysets = [queryset1, queryset2]
result_queryset = list(chain(*querysets))

Other episodes