Reputation: 4220
I have data like this:
Data Created by this query:
data = Post.objects.filter(post_by=UserID).
values_list('posted_date_time','post_id')
.union(post_wishlist.objects.filter(user_id=UserID)
.values_list('added_date_time', 'post_id'))
Can i make it better query where it provide shorted data according to date.
Output
<QuerySet [(datetime.datetime(2019, 6, 14, 20, 4, 58, 104805, tzinfo=<UTC>), UUID('b15be3c1-3f70-4ccb-af08-dba385f883a1')),
(datetime.datetime(2019, 6, 12, 18, 42, 38, 675120, tzinfo=<UTC>), UUID('f2ea2ad0-f228-43d7-823a-c824a041feb2')),
(datetime.datetime(2019, 6, 12, 17, 46, 38, 479890, tzinfo=<UTC>), UUID('16c66e9b-0cbf-4b6d-b848-78cf771f522c')),
(datetime.datetime(2019, 6, 21, 20, 17, 15, 785171, tzinfo=<UTC>), UUID ('a169afcf-267b-4212-97e5-6221595ab107')),
(datetime.datetime(2019, 6, 15, 7, 33, 34, 136331, tzinfo=<UTC>), UUID('9aac6b06-6622-4587-9956-5b517aaa11e8')),
(datetime.datetime(2019, 6, 18, 16, 11, 49, 134458, tzinfo=<UTC>), UUID('00271b56-9ff7-4f9d-b9c0-2592ca9436d2')),
(datetime.datetime(2019, 6, 21, 21, 3, 53, 528261, tzinfo=<UTC>), UUID('df0d8905-5377-4b8d-99d9-eba644273eaa')),
(datetime.datetime(2019, 6, 21, 21, 4, 6, 256957, tzinfo=<UTC>), UUID('c339d797-f37d-48ff-94a6-e6d1510e23cc')),
(datetime.datetime(2019, 6, 18, 17, 10, 18, 388505, tzinfo=<UTC>), UUID('00271b56-9ff7-4f9d-b9c0-2592ca9436d2'))]>
In the QuerySet i've multiple datetime instance with UUID,
I created this data using 2 different model and both model have different datetime field name, so i think we can't use CHAIN.
Here I want to sort according to datetime
Many Thanks in advance
Upvotes: 0
Views: 3081
Reputation: 2288
If it's a single model, you can always go for order_by which is the best approach.
class ModelA(models.Model):
timestamp = models.DateTimeField(default=timezone.now)
ModelA.objects.order_by("timestamp")
If you have multiple models, that have similar data (not necessarily fields), you can still use order_by
.
class ModelB(models.Model):
created = models.DateTimeField(default=timezone.now)
title = models.CharField(max_length=32)
ModelA.objects.values("timestamp").union(
ModelB.objects.annotate(timestamp=F("created")).values("timestamp")
).order_by("timestamp").values("timestamp")
It's important that the number of fields in both queries is exactly the same, and corresponding fields in the queries are of the same data type. (I might have used .values()
too many times here. I can't recall the syntax at the top of my head.)
This, of course, is not as readable as sorting it in python.
data_a = ModelA.objects.values("timestamp")
data_b = ModelB.objects.annotate(timestamp=F("created")).values("timestamp")
final_data = sorted(data_a + data_b, key=lambda x: x["timestamp"])
Notice that in both cases, I've annotated and added a field called timestamp
in the second model to match the name in the first. It just makes things easier.
The order_by
has two advantages over the python sorted
.order_by("-timestamp")[10]
, but
with Python, you would have to fetch all the data and then discard
most of it. This can be super expensive and wasteful when you're
dealing with large data sets.Upvotes: 2