Обратно отношение много към много с прокси модели в Django

Имам име на модел „Група“ с връзка ManyToMany с потребителя на Django и таблица „Членство“ между тях.

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'))

Когато се опитам да получа групите за потребител, всичко е наред:

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

Проблемът е, че не мога да получа потребителите за група:

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

Единственото нещо, което забелязах е, че полето „user_id“ в моята база данни (генерирана от django) няма външния ключ за таблицата auth_user, но полето „group_id“ има външния ключ за таблицата myapp_group.

Благодаря предварително.

РЕДАКТИРАНЕ:

Тук явно има нещо нередно:

>>> User.objects.get(id=2).groups.get(id=1).users.all()    
[]

person lracicot    schedule 16.06.2013    source източник
comment
Временно намерих това грозно грозното решение за добавяне на необработен sql към груповия модел: 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))   -  person lracicot    schedule 17.06.2013


Отговори (1)


За съжаление това е документиран бъг в Django ORM. Повече информация за него ще намерите тук:

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

Най-добрата алтернатива е просто да посочите модела по подразбиране. Тъй като и двете записват на едно и също място в базата данни, можете да „конвертирате“ върнатите модели от auth.models.User във вашия прокси потребителски модел, като използвате следната техника. Уверете се, че използвате този, който не попада във вашата база данни втори път.

person nicbou    schedule 17.06.2013
comment
Все още не мога да намеря потребителите за група. Мисля, че вашето решение ще се приложи, ако не успея да получа групите за даден потребител, но това не е проблем. - person lracicot; 17.06.2013
comment
Сигурен ли си, че го правиш правилно? Променете вашия външен ключ на DjangoUser вместо вашия прокси потребителски клас. - person nicbou; 17.06.2013
comment
Опитах това. Единственото нещо, което направи е, че не мога да получа връзката m2m нито от групата, нито от потребителя, нито от djangouser. Той казва: AttributeError: обектът 'ManyToManyField' няма атрибут '_m2m_reverse_name_cache'. - person lracicot; 18.06.2013
comment
Въпросът е относно наличието на поле ManyToMany към прокси модел, докато посоченият билет за грешка в Django е свързан с наличието на поле ManyToMany към прокси модел. Две напълно различни неща. - person Christian Abbott; 14.11.2019