1

I'm working on a blog. On its first page I want to show 4 random blog posts & 6 latest blog posts!

Here's what I did:

# 4 random posts
data1 = sorted(Blog.objects.all(), key=lambda x: random.random())[:4] 

# 6 latest posts (excluding the random ones)
data2 = Blog.objects.exclude(id__in=data1).order_by('-id')[:6]

# all blogs
results = list(chain(data1, data2))

But the above code is raising an error: int() argument must be a string, a bytes-like object or a number, not 'Blog'.

When I remove .exclude(id__in=data1) from data2 everything is working fine, but I need it in order to prevent duplicates.

How can we fix that? Thank You!

0

1 Answer 1

3

id__in expects a collection of integers, because the id column is of integer type. So you'll have to extract the id column from data1:

id__in=[post.id for post in data1]

EDIT: This is necessary because you converted the QuerySet from the first line into a Python list. However, see https://docs.djangoproject.com/en/2.0/ref/models/querysets/#in and order_by('?') - it's better not to convert QuerySets into lists sooner than you have to, since composing QuerySets directly will generate SQL that doesn't fetch the entire table into memory.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank You, Thank You, Thank You! Working perfectly fine now :)
No worries, glad it worked :) By the way, I have a feeling that it might be possible to use id__in=query_set if query_set is a Django QuerySet and not a simple Python list as it is here (because you used sorted). It's probably better to use QuerySets throughout to avoid fetching every single blog post in the table, if possible. (Although it would only matter if you had a large number of posts, of course.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.