i wrote this function in django model that would help send and get messages but tbh i do not understand what the code exactly does because the tutorial teacher didn't explain anything about the code and for days now i have been trying to figure out what the code does with no solutions yet. I do not just want to copy and paste code from a tutorial, i want to also understand what each code does so that's why i would appreciate anyhelp.
The code
def get_messages(user):
messages = Message.objects.filter(user=user).values('recipient').annotate(last=Max('date')).order_by('-last')
users = []
for message in messages:
users.append({
'user': User.objects.get(pk=message['recipient']),
'last': message['last'],
'unread': Message.objects.filter(user=user, recipient__pk=message['recipient'], is_read=False).count()
})
return users
complete models.py
class Message(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user')
sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name='from_user')
recipient = models.ForeignKey(User, on_delete=models.CASCADE, related_name='to_user')
body = models.TextField(max_length=1000, blank=True, null=True)
date = models.DateTimeField(auto_now_add=True)
is_read = models.BooleanField(default=False)
def send_message(from_user, to_user, body):
sender_message = Message(
user=from_user,
sender=from_user,
recipient=to_user,
body=body,
is_read=True)
sender_message.save()
recipient_message = Message(
user=to_user,
sender=from_user,
body=body,
recipient=from_user,)
recipient_message.save()
return sender_message
def get_messages(user):
messages = Message.objects.filter(user=user).values('recipient').annotate(last=Max('date')).order_by('-last')
users = []
for message in messages:
users.append({
'user': User.objects.get(pk=message['recipient']),
'last': message['last'],
'unread': Message.objects.filter(user=user, recipient__pk=message['recipient'], is_read=False).count()
})
return users
views.py if needed
def Inbox(request):
messages = Message.get_messages(user=request.user)
active_direct = None
directs = None
if messages:
message = messages[0]
active_direct = message['user'].username
directs = Message.objects.filter(user=request.user, recipient=message['user'])
directs.update(is_read=True)
for message in messages:
if message['user'].username == active_direct:
message['unread'] = 0
CodePudding user response:
Message.objects.filter(user=user).values('recipient').annotate(last=Max('date')).order_by('-last')
This will select all Messages for a specific user, of those Message object you are selecting the recipient value and the max date. This is equal to the following in SQL:
SELECT
"messages"."recipient",
MAX("messages"."date") AS "last"
FROM
"messages"
WHERE
"messages"."recipient" = x
GROUP BY
"messages"."recipient",
"messages"."date"
ORDER BY
"messages"."date" DESC
Then in the loop the user objects is retrieved by the recipient value:
'user': User.objects.get(pk=message['recipient']),
Unread will be set to the amount of messages that this user has sent to the given recipient but are still unread.
'unread': Message.objects.filter(user=user, recipient__pk=message['recipient'], is_read=False).count()
Tip: if you ever have a django query, you can just call see the SQL query by doing the following: print(Message.objects.filter(...).query)