This question is regarding Django filtering, with __In
clause. Basically, I am trying to understand how to filter by providing videos.filter(video__in = video_ids)
with string ids, so that each row that gets returned has the same order as the order of string ids in the list used for filtering.
For more context, filtering is done using string ids for e.g. ['7C2z4GqqS5E','kTlv5_Bs8aw','OK3GJ0WIQ8s','p8npDG2ulKQ','6ZfuNTqbHE8']
. Model video
field is video id described above. It is different from the integer id.
The video_id_order
used below was something I had tried that gave error Field 'id' expected a number but got '7C2z4GqqS5E'
, I believe this is not being used correctly, and something is still missing to get the order of results preserved as it is in video_ids
. What should be the correct order function in this case or is this approach even correct with Django models to preserve query-set result when __In
clause is used?
def get_video_objects(video_ids,count):
'''
video_ids are already in the correct order, filter should return rows in the same order
'''
videos = Video.objects.all()
// video_id_order = Case(*[When(id=id, then=pos) for pos,id in enumerate(video_ids)])
results = videos.filter(video__in = video_ids)
// results = results.order_by(video_id_order)
results = list(results[:int(count)]\
.values('video','title','comment_count','likes'))
return results
Video model is as following
class Video(models.Model):
id = models.PositiveBigIntegerField(primary_key=True,serialize=False,auto_created=False)
video = models.SlugField(unique=True,null=False,primary_key=False)
title = models.CharField(max_length=200)
comment_count = models.PositiveIntegerField(default=0)
likes = models.PositiveIntegerField(default=0)
Try changing "id" param to "video" in the Case() since you are iterating over the strings
video_id_order = Case(*[When(video=id, then=pos) for pos,id in enumerate(video_ids)])
results = videos.filter(video__in = video_ids)
results = results.order_by(video_id_order)
`