filtrar por muitos para muitos campo

votos
1

então eu tenho este modelo:

class Message(models.Model):
    creator = models.ForeignKey(User, unique=True)
    note = models.CharField(max_length=200, blank=True)
    recipients = models.ManyToManyField(User, related_name=shared_to)
    read = models.ManyToManyField(User, related_name=read, blank=True)

Eu quero filtrar as pessoas que estão em ambos os destinatários e ler, atualmente eu estou fazendo isso.

messages = user.shared_to.all()

for message in messages:
    if user not in message.read:
        do something

Eu tenho certeza que há uma maneira de filtrar isso, mas eu não consigo descobrir como.

Publicado 16/04/2009 em 21:06
fonte usuário
Em outras línguas...                            


2 respostas

votos
1

Se você usar a versão de desenvolvimento do Django, ou esperar até que a versão 1.1 é liberado, em seguida, os filtros podem fazer referência a outros campos no modelo . Assim, sua consulta seria algo como isto:

>>> Message.objects.filter(recipients=F('read'))

(Nota: eu escrito reciepients o mesmo que você tinha em seu modelo, embora a grafia correta seria "destinatários")

Editar :

Ok, sua pergunta é confusa. Quando eu dei a resposta acima eu estava lendo a sua declaração de que você queria que todos os usuários que estavam em ambos os "receptores" e "ler"). Mas depois de ler o seu trecho de código parece que você quer uma lista de usuários que são destinatários, mas ainda não na lista de "ler".

Este é provavelmente o que você quer, mas eu não estou completamente certo por causa dos requisitos vagos e não posso rapidamente testá-lo:

# Get list of recipients
shared_to = Message.shared_to.all().values('id')

# Now list of recipients who are not in the read field
unread = Message.objects.exclude(recipients__in=shared_to)

Isso fará com que uma única consulta, mas se você estiver usando o MySQL ainda poderia ser mais eficiente para fazer duas consultas (leia o aviso de considerações Performance).

Respondeu 16/04/2009 em 21:30
fonte usuário

votos
0

Eu acho que eu originalmente interpretado mal sua pergunta. Tente o seguinte consulta.

for message in user.shared_to.exclude(read__id__in=[user.id]):
  do_something()
Respondeu 16/04/2009 em 21:22
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more