title: Django model queryset using related names and managers
body: <p>I have 4 models - </p>
  
  <pre><code>class Group(models.model):
      group_id = models.CharField(max_length=10)
      name = models.CharField(max_length=20)
  
  class User(models.model):
      user_id = models.CharField(max_length=10)
      grp = models.ForeignKey(Group, null=True, blank=True)
      user_name = models.CharField(max_length=50)
      contact_no = models.CharField(max_length=20)
  
  class DesigType(models.model):
      desig_name = models.CharField(max_length=10)
  
  class Designation(models.model):
      user = models.ForeignKey(User, null=True, blank=True, related_name='desigs')
      desig_type = models.ForeignKey(DesigType, null=True, blank=True, related_name='desigs')
  </code></pre>
  
  <p><code>Group</code> model holds groups of users. <code>User</code> holds records for each individual user. <code>DesigType</code> has information about "type of designation", like maybe manager, team lead etc. <code>Designation</code> stores the exact designation - for example, for manager <code>DesigType</code>, <code>Designation</code> might have project manager or account manager; similarly, for team lead <code>DesigType</code>, <code>Designation</code> might have front-end lead or back-end lead.</p>
  
  <p>The UI currently shows a list of users under a group. I want to implement a search functionality according to <code>desig_name</code>. The UI sends me the <code>group_id</code> and the text entered by the end-user in the search box, and I have to return only those <code>User</code>s which have the corresponding <code>desig_name</code>.</p>
  
  <p>I have already done the above, by using a <code>property</code> to return a list of <code>desig_name</code>s that a <code>User</code> has and checking whether the user input exists in the list.</p>
  
  <p>This is a <code>property</code> under <code>User</code> - </p>
  
  <pre><code>@cached_property
  def desig_types(self):
      desig_types = []
      for value in self.desigs.select_related('desig_type').values('desig_type__desig_name'):
          desig_types.append(value['desig_type__desig_name'])
      return desig_types
  </code></pre>
  
  <p>In my view I have a generic search function which takes any user filter to return the appropriate list of users.</p>
  
  <pre><code>group = Groups.objects.get(pk=grp_id)
  _queryset = group.user_set.filter(**user_filter)
  </code></pre>
  
  <p>The above code works for filtering according to <code>contact_no</code> and <code>user_name</code>. For <code>contact_no</code>, <code>**user_filter</code> is <code>group.user_set.filter(contact_no=user_input)</code>, and for <code>user_name</code>, it's <code>group.user_set.filter(user_name=user_input)</code>. I want it to also work for filtering according to <code>desig_name</code>, but I couldn't figure out how to navigate through the relationships so I wrote the code below, that retrieves a list of <code>user_id</code>s which have the user inputted <code>desig_name</code>.</p>
  
  <pre><code>required_users = []
  for user in group.user_set.all():
          user_desig_names = user.desig_types
          if user_input in user_desig_names:
              required_users.append(user.user_id)
  return required_users
  </code></pre>
  
  <p>I then pass in the filter as <code>group.user_set.filter(user_id__in=required_users)</code>. But as you see, I have to have an additional code to get the <code>user_id</code>s, instead of directly using <code>**user_filter</code>, like with <code>user_name</code> or <code>contact_no</code>. </p>
  
  <p>Does anyone know how I can do that?</p>