I am making a kind of social network in Django. This explains basically what I'm doing:
Django - Private messaging conversation view
The conversations are exclusively between two people, not more. I have a conversation model because when they to their messages, I want the user to have a list of the other users that they have messages with.
Here is the relevant view:
def writemessage(request, id):
profile = Profile.objects.get(id=id)
context = {
'profile': profile,
}
if request.method == 'POST':
sender = request.user
receiver = profile.user
content = request.POST['content']
timestamp = datetime.now()
print(sender, receiver, content, timestamp)
record = Message(sender=sender, receiver=receiver, content=content, timestamp=timestamp)
record.save()
senderprofile = Profile.objects.get(user=sender)
receiverprofile = Profile.objects.get(user=receiver)
record.conversation.add(senderprofile)
record.conversation.add(receiverprofile)
print(senderprofile, receiverprofile)
return redirect('messagespage')
return render(request, 'thecode/writemessage.html', context)
Here are my models:
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
city = models.CharField(max_length=60)
country = models.CharField(max_length=60)
skillstolearn = models.CharField(max_length=200)
skillstoteach = models.CharField(max_length=200)
description = models.TextField()
def __str__(self):
return self.user.username
class Conversation(models.Model):
participants = models.ManyToManyField(User)
def __str__(self):
return self.participants
class Message(models.Model):
sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name='sender')
receiver = models.ForeignKey(User, on_delete=models.CASCADE, related_name='receiver')
content = models.TextField()
conversation = models.ForeignKey(Conversation, default=None, on_delete=models.CASCADE, null=True)
timestamp = models.DateTimeField()
def __str__(self):
return self.sender.username + ' to ' + self.receiver.username
I know about some documentation:
https://docs.djangoproject.com/en/dev/ref/models/relations/
I've tried to understand the documentation and also posts on here but am a little bit stuck.
'NoneType' object has no attribute 'add' = the error messages that I get
The Message
object's conversation
field is None
by default, and your view function doesn't set conversation
before trying to read it. You need to figure out what Conversation
this message belongs in, and then set it when you construct the Message
:
record = Message(conversation=???, sender=sender, receiver=receiver, content=content, timestamp=timestamp)
record.save()
How do you know which conversation a User
is in?
A few code review notes:
related_name
arguments for your ForeignKey
fields indicate the name of the field on the User
model that refers back to the Message
model, not the other way around. Therefore, instead of sender
and receiver
, they should be messages_sent
and messages_received
. Please update your original posting to improve the clarity.
# Example of accessing sent and received messages from a User model:
user.messages_sent
user.messages_received