I'm creating a messaging system and part of what I want to do is based on whether the user is a sender or a receiver of a message, different CSS loads. I'm trying to achieve this by attaching a property to each message object that identifies this.
I have my message
#models.py
class Message(models.Model):
def __unicode__(self):
return unicode(self.time_date)
message_from = models.ForeignKey(User, related_name="%(class)s_message_from")
message_to = models.ForeignKey(User, related_name="%(class)s_message_to")
message = models.TextField()
file = models.FileField(blank=True, null=True)
read = models.BooleanField(default=False)
time_date = models.DateTimeField(default=django.utils.timezone.now)
job = models.ForeignKey(Job, blank=True, null=True)
and my view to get the messages:
def view_messages(request):
messages = Message.objects.filter(message_to=request.user, job_id=None).distinct('message_from')
messages_from_user_ids = messages.values_list('message_from', flat=True).distinct()
messages_from_user = User.objects.filter(id__in=messages_from_user_ids)
messages = Message.objects.filter(
Q(message_to=request.user) & Q(message_from_id=messages_from_user_ids[0]) & Q(job_id=None) | Q(
message_from_id=messages_from_user_ids[0]) & Q(
message_from_id=request.user) & Q(job_id=None)).order_by('time_date')
messages = Message.objects.annotate(foo='true') # error
return render(request, 'freelancestudent/general/messages.html', {'messages': messages,
'messages_from': messages_from_user})
What I was trying to achieve in the line commented error was to simply test annotations by annotating the string 'true'
to every message object, accessible under foo
. This gives me the error 'str' object has no attribute 'resolve_expression'
.
What I'm ultimately trying to achieve, in case I'm going about this the wrong way, is to check if the user is the sender. The idea i had of achieving it was to do something like this:
for message in messages:
if message_from == request.user.id:
messages.annotate(sender=True)
Though, this isn't the right syntax. I'm not sure annotate
is the right function, either. Any ideas?
If you are looping through the queryset, don't try to use annotate
, just set an attribute on the instance.
for message in messages:
if message_from == request.user.id:
message.sender = True
Alternatively, I think you could use annotate
with Case
:
from django.db.models import BooleanField, Case, Value, When
messages = Message.annotate(
sender=Case(
When(message_from=request.user, then=Value(True)),
default=Value(False),
output_field=BooleanField(),
)
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With