[Answer]-Django many-to-many lookup from different models

1👍

You can get the Notes of a user by using the following query:

For example let us think that a user’s id is 1 and we want to keep it in variable x so that we can use it in query. So the code will be like this:

>>x = 1
>>Note.objects.filter(Q(**{'%s_id' % 'worker__department__company__user' : x})|Q(**{'%s_id' % 'document__company__user' : x})|Q(**{'%s_id' % 'company__user' : x})|Q(**{'%s_id' % 'department__company__user' : x})).distinct()

Here I am running OR operation using Q and distinct() at the end of the query to remove duplicates.

EDIT:

As I mentioned above I know how to do this by enumerating all models
(Company, Worker, etc. ). But if I will create a new model (in another
App for example) that also can generate Notes, I have to change code
in the View in another App, and that’s not good.

In my opinion, if you write another model, how are you suppose to get the notes from that model without adding new query? Here each class (ie. Department, Worker) are separately connected to Company and each of the classes has its own m2m relation with Note and there is no straight connection to User with Note‘s of other classes(except Company). Another way could be using through but for that you have change the existing model definitions.

Another Solution:

As you have mentioned in comments, you are willing to change the model structure if it makes your query easier, then you can try the following solution:

class BaseModel(models.Model):
    user = models.Foreignkey(User)
    note = models.ManyToManyField(Note)
    reports_to = models.ForeignKey('self', null=True, default=None)


class Company(BaseModel):

    class Meta:
       proxy = True


class Document(BaseModel):

    class Meta:
      proxy = True

#And so on.....

Advantages: No need to create separate table for document/company etc.

object creation:

>>c= Company.objects.create(user_id=1)
>>c.note.add(Note.objects.create(text='Hello'))
>>d = Document.objects.create(user_id=1, related_to=c)
>>d.note.add(Note.objects.create(text='Hello World'))
👤ruddra

Leave a comment