Django - filtrando em propriedades de chave estrangeira

105

Estou tentando filtrar uma tabela no Django com base no valor de um campo específico de a ForeignKey.

Por exemplo, tenho dois modelos:

class Asset(models.Model):
    name = models.TextField(max_length=150)
    project = models.ForeignKey('Project')

class Project(models.Model):
    name = models.TextField(max_length=150)

Gostaria de filtrar minha lista de ativos com base no nome do projeto associado.

Atualmente, estou realizando duas consultas:

project_list = Project.objects.filter(name__contains="Foo")
asset_list = Asset.objects.filter(desc__contains=filter,
                                  project__in=project_list).order_by('desc')

Estou me perguntando se existe uma maneira de especificar esse tipo de filtragem na consulta principal?

Fraser Graham
fonte

Respostas:

167

Asset.objects.filter( project__name__contains="Foo" )

Fragsworth
fonte
1
Obrigado, eu tentei isso, mas aparentemente me esqueci de usar o sublinhado duplo.
Fraser Graham
3
é necessário ??
DeadDjangoDjoker
@DeadDjangoDjoker containsdescreve o tipo de comparação usado na consulta que o django ORM produz, o sql provavelmente será semelhante LIKE '%Foo%'.
orangecaterpillar
17

Isso tem sido possível desde que a queryset-refactoragência chegou ao pré-1.0. O ingresso 4088 expôs o problema. Isso deve funcionar:

Asset.objects.filter(
    desc__contains=filter,
    project__name__contains="Foo").order_by("desc")

A documentação do Django muitos-para-um tem este e outros exemplos das seguintes chaves estrangeiras usando a API do modelo.

Michael Greene
fonte
1
Isso vai atingir o banco de dados duas vezes, devo usar select_related () para tornar isso mais ideal?
Fraser Graham
5
Você pode adicionar um .query.as_sql () para ver qual sql será realmente executado.
multiplicação rápida
o link para os documentos do django está completamente desatualizado e
leva
0
student_user = User.objects.get(id=user_id)
available_subjects = Subject.objects.exclude(subject_grade__student__user=student_user) # My ans
enrolled_subjects = SubjectGrade.objects.filter(student__user=student_user)
context.update({'available_subjects': available_subjects, 'student_user': student_user, 
                'request':request, 'enrolled_subjects': enrolled_subjects})

Em minha aplicação acima, presumo que, uma vez que um aluno esteja matriculado, uma instância de SubjectGrade da disciplina será criada contendo a disciplina matriculada e o próprio aluno.

O modelo Assunto e Usuário Aluno é uma chave estrangeira para o modelo SubjectGrade.

Em "available_subjects", eu excluí todas as disciplinas que já estão matriculadas pelo student_user atual, verificando todas as instâncias de subjectgrade que têm o atributo "student" como o student_user atual

PS. Peço desculpas antecipadamente se você ainda não consegue entender por causa da minha explicação. Esta é a melhor explicação que posso fornecer. muito obrigado

Kinowe
fonte
Acho que será ótimo editar e adicionar algum texto, explicação ou comentário ao bloco de código para colocá-lo em contexto.
Elisha Senoo
Eu forneço uma explicação. Obrigado @ElishaSenoo
Kinowe