#django #feed
#django #канал
Вопрос:
На моем сайте у меня есть три модели, организованные в двух приложениях, все эти модели имеют timestamp
поле, которое определяет порядок отображения в ленте сайта. Вместо того, чтобы создавать канал для каждой модели и выполнять отдельные запросы, упорядоченные по timestamp
полю, я хочу сгенерировать один канал, содержащий все эти объекты, отображая каждый из них с соответствующим шаблоном, и все они упорядочены по timestamp
атрибуту.
Моей первой попыткой было бы перечислить все объекты и объединить их в один список и отсортировать их в Python:
class SiteFeed(Feed):
...
def items(self):
objects = list(model1.objects.all()) list(model2.objects.all()) list(model3.objects.all())
objects.sort(key=lamda obj: obj.timestamp)
return = objects
Ответ №1:
Я бы вернул итератор из items
метода. в этом случае сортировка и агрегирование объектов могут выполняться ленивым способом. Если вы предварительно отсортируете три коллекции объектов, которые хотите объединить, перед созданием итератора, окончательная сортировка — это просто вопрос выбора следующего объекта из нужной коллекции на каждой итерации. Вы понимаете, что я имею в виду?
например:
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
Комментарии:
1. Я не привык к итераторам, не могли бы вы предоставить пример кода, чтобы проиллюстрировать свой ответ? Я не вижу, как построить этот итератор, но я думаю, что понимаю общую идею.
2. Это простой итератор. Проблема все еще остается, мне нужны все эти объекты разных моделей, отсортированные по общему атрибуту
timestamp
. В этом коде возвращаются толькоmodel1
объекты.3. да, я привел вам только пример, поскольку вы сказали, что не привыкли к итераторам. Я снова обновил свой ответ, чтобы дать вам лучшее представление о том, что я имею в виду. Извините, у меня нет времени на написание полного решения. Это псевдокод, я ничего не тестировал.
4. Хорошо, я попробую это и вернусь с комментариями. Спасибо!