I have been researching this for a couple days. Unfortunately, all of the proposed solutions I have found so far don't exactly work for me.
I am looking to manually combine two Django QuerySets into a single Django model, which I then want to serialize using a Django Rest Framework serializer. I then use the serializer for outputting JSON.
I have found various solutions on SO suggesting the use of itertools and chain, but it is unclear then how to serialize the result of chain.
Note that my goal here is for web application performance purposes. Each QuerySet works fine independently, but it requires two separate Ajax calls to retrieve the results. I would prefer to make only one Ajax call, manually combine the results on the server-side, then return the combined JSON.
This SO answer is close, but I can't figure out how to serialize the result of a chain, using DRF serializers.
You can also use the chain() method from the Itertools module, which allows you to combine two or more QuerySets from different models through concatenation. Alternatively, you can use union() to combine two or more QuerySets from different models, passing all=TRUE if you want to allow duplicates.
Use union operator for queryset | to take union of two queryset. If both queryset belongs to same model / single model than it is possible to combine querysets by using union operator. One other way to achieve combine operation between two queryset is to use itertools chain function.
Serialization and Deserialization The first thing we need for our API is to provide a way to serialize model instances into representations. Serialization is the process of making a streamable representation of the data which we can transfer over the network. Deserialization is its reverse process.
It is not necessary to use a serializer. You can do what you would like to achieve in a view. However, serializers help you a lot. If you don't want to use serializer, you can inherit APIView at a function-based-view.
After a couple more days of Googling for answers to this problem, I finally stumbled on this page which explains how to do pretty much what I wanted to do. I have posted my own answer here in case someone else has the same problem.
The technique seems simple enough now that I understand it, but I had a hard time finding anything online describing this technique. Basically, you chain together multiple querysets, then convert the chain to a Python list. Then iterate the list, manually calling the correct serializer, and appending to a dictionary. Then you can dump the dictionary to JSON.
I have posted the relevant code in case that link goes dead:
def get_queryset(self):
queryset_a = Post.objects.all()
queryset_b = FriendRequest.objects.filter(is_unanswered=True)
# Create an iterator for the querysets and turn it into a list.
results_list = list(chain(queryset_a, queryset_b))
# Optionally filter based on date, score, etc.
sorted_list = sorted(results_list, key=lambda instance: -instance.date_created)
# Build the list with items based on the FeedItemSerializer fields
results = list()
for entry in sorted_list:
item_type = entry.__class__.__name__.lower()
if isinstance(entry, Post):
serializer = PostSerializer(entry)
if isinstance(entry, FriendRequest):
serializer = FriendRequestSerializer(entry)
results.append({'item_type': item_type, 'data': serializer.data})
return results
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With