Приложение для чата Django сортирует сообщения по дате
У меня есть чат и модель сообщений. Как я могу отсортировать мой чат по дате создания_сообщения Пример: предположим, что я нахожусь в двух чатах (A и B): я хочу, чтобы каждый раз, когда я получаю сообщение от B, B был ниже A, а когда я получаю сообщение от A, A был ниже B. Я потратил много времени, чтобы сделать это, но успеха не было.
Models.py
`class Chat(models.Model):
creation_date = models.DateField(default=timezone.now)
id = models.AutoField(primary_key=True)
content = models.TextField()
sender = models.ForeignKey(
BasicUserProfile,
on_delete=models.CASCADE,
blank=True,
null=True,
related_name="sender"
)
reciever = models.ForeignKey(
BasicUserProfile,
on_delete=models.CASCADE,
blank=True,
null=True,
related_name="reciever"
)
class Meta:
ordering = ["-creation_date"]
def __str__(self):
return "chat: " + str(self.sender)`
views.py
single.html
` <div id="chat-right-middle-box">
<div id="chat-self-box">
{% for chat_record in chat_history_feed %}
<p> {{chat_record.content}}</p>
{% endfor %}
</div>`
Я пытался отделиться и создать новую модель вместо чата, но это была не лучшая идея.
сначала:
Для возврата obj=None
на ObjectDoesNotExist
у Django есть специальные методы first/last:
Вместо этого:
try:
current_reciever_user = User.objects.get(username=username)
except ObjectDoesNotExist:
current_reciever_user = None
используйте это:
current_reciever_user = User.objects.filter(username=username).first()
Во-вторых. Лучше сортировать на уровне базы данных, а не в питоне:
from django.db.models import Case, Value, When
....
# define which chat you want to see
chat = ???
# define if chat=A, sender=A - priority 1
# define if chat=B, sender=A - priority 2
# define if chat=A, sender=B - priority 2
# define if chat=B, sender=B - priority 1
priority = Case(
When(Q(sender=A), then=Value(int(chat==A or 2))),
When(Q(sender=B), then=Value(int(chat==B or 2))),
then=Value(3)),
)
# define queryset
chats = Chat.objects.all()
# add filter by sender
chats = chats.filter(
Q(sender=current_basic_user_profile) | Q(sender=current_reciever))
# add filter by receiver
chats = chats.filter(Q(receiver=current_basic_user_profile) | Q(receiver=current_reciever))
# right now you have all wanted chats.
# add priority calculation, .alias() is like .annotation()
chats = chats.alias(priority_order=priority_order)
# Finally add ordering:
chats = chats.order_by("-creation_date", "priority")
Если я правильно понял ваш ход - вы получаете за чат A:
on 20.05.2023
all A,
all B,
on 19.05.2023
all A,
all B,
etc.
И вы получаете за чат B:
on 20.05.2023
all B,
all A,
19.05.2023
all B,
all A,
etc.
Дополнительная информация о Case When
в django:
https://docs.djangoproject.com/en/5.0/ref/models/conditional-expressions/#conditional-expressions
Дополнительная информация о alias
:
https://docs.djangoproject.com/en/5.0/ref/models/querysets/#alias
Удачи!