2

I have a model name 'Group' with a ManyToMany relationship with the Django User, and a 'Membership' table between.

class UserManager(models.Manager):get_query_set(self):
        return super(UserManager, self).get_query_set().select_related('expenses')

class User(DjangoUser):
    objects = UserManager()
    class Meta:
        proxy = True

class Group(models.Model):
    name = models.CharField(verbose_name=_('Name'), max_length=255)
    users = models.ManyToManyField(User, related_name='groups', through='Membership')

class Membership(models.Model):
    user = models.ForeignKey(User)
    group = models.ForeignKey(Group)
    date_joined = models.DateField(auto_now_add=True, verbose_name=_('Date joined'))

When I try to get the groups for a user, everything is fine:

>>> User.objects.get(id=2).groups.all()    
[<Group: Group object>]
>>> User.objects.get(id=2).groups.get(id=1)
<Group: Group object>

The problem is that I can't get the users for a group:

>>> Group.objects.get(id=1).users.all()    
[]

The one thing I noticed is that the field 'user_id' in my database (generated by django) does not have the foreign key for the auth_user table, but the 'group_id' field has the foreign key for the myapp_group table.

Thanks in advance.

EDIT:

There is clearly something wrong here:

>>> User.objects.get(id=2).groups.get(id=1).users.all()    
[]
lracicot
  • 364
  • 2
  • 15
  • I temporarily found this ugly the ugly solution to add raw sql to the group model: def get_users(self): return User.objects.raw('SELECT * FROM '+User._meta.db_table+' JOIN '+Membership._meta.db_table+' ON '+Membership._meta.db_table+'.user_id = '+User._meta.db_table+'.id WHERE '+Membership._meta.db_table+'.group_id = '+str(self.id)) – lracicot Jun 17 '13 at 02:45

1 Answers1

1

This is unfortunately a documented bug in the Django ORM. You will find more information about it here:

https://code.djangoproject.com/ticket/17299

The best alternative is to simply point to the default model. Since both save to the same place in the database, you can "convert" the returned models from auth.models.User to your proxy user model using the following technique. Make sure you use the one that doesn't hit your database a second time.

Community
  • 1
  • 1
nicbou
  • 1,047
  • 11
  • 16
  • I am still unable to get the users for a group. I think your solution would apply if I were unable to get the groups for a user, but that's not a problem. – lracicot Jun 17 '13 at 01:36
  • Are you sure you are doing it correctly? Change your foreignkey to DjangoUser instead of your proxy user class. – nicbou Jun 17 '13 at 12:30
  • I tried that. The only thing it did is that I can't get the m2m relation from neither the group or the user or the djangouser. It says: AttributeError: 'ManyToManyField' object has no attribute '_m2m_reverse_name_cache'. – lracicot Jun 18 '13 at 03:56
  • 1
    The question is about having a ManyToMany field *to* a proxy model, whereas the referenced Django bug ticket is about having a ManyToMany field *on* a proxy model. Two completely different things. – Christian Abbott Nov 13 '19 at 23:09