开发者

What's the best way to generate a single feed from different models?

开发者 https://www.devze.com 2023-04-09 20:51 出处:网络
In my site, I have three models, organized in two apps, All this models have a timestamp field, which defines the order of appearance in the site\'s feed. Instead of creating a feed for every model an

In my site, I have three models, organized in two apps, All this models have a timestamp field, which defines the order of appearance in the site's feed. Instead of creating a feed for every model and making single queries ordered by the timestamp field, I want to generate a single feed that contains all this objects, rendering each one with their corresponding template, and all of them ordered by the timestamp attribute.

My first attempt would be listing all objects and combining them in a single list and sort them within Python:

class SiteFeed(Feed):
    ...
    def items(self):
        objects = list(model1.objects.all()) + list(model2.objects.all()) + list(model3.objects.all())
       开发者_JS百科 objects.sort(key=lamda obj: obj.timestamp)
        return = objects


I would return an iterator from the items method. in this case sorting and aggregation of objects can be done in a lazy manner. If you pre-sort the three collections of the objects that you want to combine before you construct the iterator, the final sorting is just a matter of choosing the next object from the right collection on each iteration. Do you see what I mean?

for example:

class SiteFeed(Feed):
    ...
    def items(self):
        i = model1.objects.order_by('timestamp').iterator()
        j = model2.objects.order_by('timestamp').iterator()
        k = model3.objects.order_by('timestamp').iterator()
try: u = i.next() except StopIteration: u = None
try: v = j.next() except StopIteration: v = None
try: w = k.next() except StopIteration: w = None ... yield min([u,v,w], key=lambda x: x.timestamp if x else datetime.max) ... # at this point you need to reiterate the iterator # corresponding to the variable that you yielded # and yield again # so, the above code must be in some sort of a loop # until ALL iterators are exhausted

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号