Отношение `` многие ко многим '' с прокси-моделями в 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