Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a query on related_name field?

I have to models connected by a ForeignKey

class User(AbstractUser):
   ...

and

class PrivateMessage(models.Model):
    user_from = models.ForeignKey(
        User,
        verbose_name=u'From',
        related_name='sent_messages',
    )
    user_to = models.ForeignKey(
        User,
        verbose_name=u'To',
        related_name='received_messages',
    )

Is there any way to get all the addresses for a particular user. For example, if

u = User.objects.get(id=1)
messages = PrivateMessage.objects.filter(user_from=u)
for m in messages:
    users.add(m.user_to)

How to obtain a list of users that appear in user_to for these messages using only Django ORM methods?

like image 782
cansadadeserfeliz Avatar asked Nov 27 '13 14:11

cansadadeserfeliz


People also ask

How do I query in Django?

You get a QuerySet by using your model's Manager . Each model has at least one Manager , and it's called objects by default. Access it directly via the model class, like so: >>> Blog.objects <django.db.models.manager.Manager object at ...> >>> b = Blog(name='Foo', tagline='Bar') >>> b.objects Traceback: ...

What is related query name in Django?

The related_name attribute specifies the name of the reverse relation from the User model back to your model. If you don't specify a related_name, Django automatically creates one using the name of your model with the suffix _set.

What is PK in Django?

pk is short for primary key, which is a unique identifier for each record in a database. Every Django model has a field which serves as its primary key, and whatever other name it has, it can also be referred to as "pk".


1 Answers

I think a better idea would be to define ManyToManyField on the User model:

class User(AbstractUser):
    #...
    receivers = models.ManyToManyField('self', through='Message',
                                      symmetrical=False, related_name="senders")

class Message(models.Model):
    user_from = models.ForeignKey(MyUser, related_name='messages_from')
    user_to = models.ForeignKey(MyUser, related_name='messages_to')
    message = models.CharField(max_length=100, default="")
    #...

Then to retrieve users list on the other end you simply do:

User.objects.get(id=1).receivers.all()  # who I sent the message to
User.objects.get(id=1).senders.all()    # who sent me a message

This way you have a nice clear API.

like image 64
mariodev Avatar answered Oct 07 '22 16:10

mariodev