Reputation: 3611
What I want to do is, whenever I create a new message, I want the sender
of the Message
to be added to the user
of that particular Thread
(the Message
its relating to).
How do I do that? Can it be done by overriding the save
method? I can do it in the views.py, but I was hoping it would be better if I can add it in the models.py itself. Any help will be very grateful. Thank you!
class Thread(models.Model):
user = models.ManyToManyField(User)
is_hidden = models.ManyToManyField(User, related_name='hidden_thread', blank=True)
def __unicode__(self):
return unicode(self.id)
class Message(models.Model):
thread = models.ForeignKey(Thread)
sent_date = models.DateTimeField(default=datetime.now)
sender = models.ForeignKey(User)
body = models.TextField()
is_hidden = models.ManyToManyField(User, related_name='hidden_message', blank=True)
def __unicode__(self):
return "%s - %s" % (unicode(self.thread.id), self.body)
Upvotes: 2
Views: 180
Reputation: 37364
If you don't want to actively pull the user set as dm03514 showed, such as if you want to add users to the thread by default but maintain the ability to remove them from the thread many-to-many later, you can indeed do this by overriding the save
method or by using a post_save
signal.
save
is good enough for almost all cases - the advantage of post_save
is that it can more reliably distinguish between saving a new message and saving edits to an existing message. But if you're not creating messages with preselected PKs or loading them from fixtures save
can work fine:
class Message(models.Model):
def save(self, *args, **kwargs):
probably_new = (self.pk is None)
super(Message, self).save(*args, **kwargs)
if probably_new:
self.thread.user.add(self.sender)
A signal would look like this:
from django.db.models.signals import post_save
def update_thread_users(sender, **kwargs):
created = kwargs['created']
raw = kwargs['raw']
if created and not raw:
instance = kwargs['instance']
instance.thread.user.add(instance.sender)
post_save.connect(update_thread_users, sender=Message)
And then review the docs on preventing duplicate signals in case of multiple imports: https://docs.djangoproject.com/en/dev/topics/signals/#preventing-duplicate-signals
Upvotes: 3
Reputation: 55972
You could lookup the reverse foreign key and get all the users for a particular thread without having to manually put it in Thread
Then you can get users associated with a thread by the reverse lookup:
User.objects.filter(message__thread=thread)
Upvotes: 4