Кажется, вы пропустили линию, прежде чем запрашивать поля: -
HistoryItem todayHistoryItem = getMood2(todayDate);
Я не вижу отличного способа сделать то, что Вы пытаетесь сделать непосредственно. Если бы Вы готовы принять немного денормализации, я рекомендовал бы сигналу перед сохранением отметить сообщения, как являющиеся в голове.
#In your model
head = models.BooleanField(default=True)
#As a signal plugin:
def check_head(sender, **kwargs):
message = kwargs['instance']
if hasattr(message,'no_check_head') and message.no_check_head:
return
previous_message = Message.objects.filter(time__lt=message.time).order_by('-time')[0]
if message.source == previous_message.source:
message.head = False
next_message = Message.objects.filter(time__gt=message.time).order_by('time')[0]
if message.source == next_message.source:
next_message.head = False
next_message.no_check_head
next_message.save()
Затем Ваш запрос становится волшебно простым:
messages = Message.objects.filter(head=True).order_by('time')[0:15]
Чтобы быть довольно честным..., слушатель сигнала должен был бы быть немного более сложным, чем тот, которого я записал. Существует хост потерянных проблем обновления синхронизации/терять, свойственных от моего подхода, решений, к которым будет варьироваться в зависимости от Вашего сервера (если он будет единственно обработан, многопоточный, затем Python Lock
объект должен получить Вас, но если он будет мультиобработан, то затем необходимо будет действительно реализовать блокировку на основе файлов или объектов базы данных). Кроме того, необходимо будет, конечно, также записать, что соответствие удаляет слушателя сигнала.
Очевидно, это решение включает добавление некоторых хитов базы данных, но они находятся на редактировании в противоположность выставленному для обозрения, который мог бы стоить для Вас. Иначе, возможно, рассмотрите более сырой подход: захватите 30 историй, цикл через в представлении, выведите тех из строя, Вы не отобразитесь, и если Вы уезжаете 15, отображаете их, иначе повторитесь. Определенно ужасный худший вариант, но возможно не ужасный средний случай?
Если бы у Вас была конфигурация сервера, которая использовала единственный процесс, это является многопоточным, то Блокировка или RLock должны добиться цели. Вот возможная реализация с неповторно используемой блокировкой:
import thread
lock = thread.allocate_lock()
def check_head(sender, **kwargs):
# This check must come outside the safe zone
# Otherwise, your code will screech to a hault
message = kwargs['instance']
if hasattr(message,'no_check_head') and message.no_check_head:
return
# define safe zone
lock.acquire()
# see code above
....
lock.release()
Снова, соответствие удаляют сигнал, очень важно также.
Править: Многие или большинство конфигураций сервера (таких как Apache) предварительно разветвятся, подразумевая, что существует несколько продолжений процессов. Вышеупомянутый код будет бесполезен в этом случае. Посмотрите эту страницу для идей о том, как начать синхронизироваться с разветвленными процессами.
У меня есть простое, хотя не идеальное, решение только для шаблона для этого. В шаблоне можно перегруппировать записи с помощью regroup
тег шаблона. После перегруппировки Вас может скрыть последовательные записи от того же источника:
{% regroup records by source as grouped_records %}
{% for group in grouped_records %}
{% for item in group.list %}
<li{% if not forloop.first %} style="display:none"{% endif %}>
{{ item.message }} {{ iterm.source }}
{% if forloop.first %}
{% ifnotequal group.list|length 1 %}
<a href="#" onclick="...">Show more from the same source...</a>
{% endifnotequal %}
{% endif %}
</li>
{% endfor %}
{% endfor %}
Это было бы прекрасно, если бы это не было, с одной стороны: Разбиение на страницы. Если Вы означаете отображать 15 объектов на страницу, и на одной странице первые пять являются fromone источником, следующими пятью от другого и последними еще одними пятью, на странице было бы только три видимых объекта.