Django - фильтрация по свойствам внешнего ключа

108

Я пытаюсь отфильтровать таблицу в Django на основе значения определенного поля ForeignKey .

Например, у меня две модели:

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

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

Я хочу отфильтровать свой список активов на основе имени связанного проекта.

В настоящее время я выполняю два запроса:

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

Мне интересно, есть ли способ указать такую ​​фильтрацию в основном запросе?

Фрейзер Грэм
источник

Ответы:

172

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

Fragsworth
источник
1
Спасибо, я пробовал это, но, видимо, я забыл использовать двойное подчеркивание.
Фрейзер Грэм,
3
содержит необходимое ??
DeadDjangoDjoker
@DeadDjangoDjoker containsописывает тип сравнения, используемый в запросе, который производит ORM django, sql, вероятно, будет выглядеть так LIKE '%Foo%'.
orangecaterpillar
17

Это стало возможным с тех пор, как queryset-refactorветка вышла до версии 1.0. Билет 4088 выявил проблему. Это должно работать:

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

В документации Django Many-to-one есть этот и другие примеры отслеживания внешних ключей с использованием API модели.

Майкл Грин
источник
1
Будет ли это дважды ударить по БД, следует ли использовать select_related (), чтобы сделать это более оптимальным?
Фрейзер Грэм,
5
Вы можете добавить .query.as_sql (), чтобы увидеть, какой sql на самом деле будет выполняться.
fastmultiplication
ссылка на django docs полностью устарела и попадает на страницу «410 Страница удалена»: - /
szeitlin
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})

В моем приложении, приведенном выше, я предполагаю, что после зачисления студента будет создан экземпляр SubjectGrade объекта, который будет содержать зарегистрированный объект и самого студента.

Модель Subject и Student User - это внешний ключ к модели SubjectGrade.

В «available_subjects» я исключил все предметы, которые уже зарегистрированы текущим student_user, проверив все экземпляры subjectgrade, у которых есть атрибут «student» как текущий student_user.

PS. Заранее приносим свои извинения, если вы все еще не можете понять из-за моего объяснения. Это лучшее объяснение, которое я могу дать. огромное спасибо

Кинове
источник
Я думаю, что было бы здорово отредактировать и добавить текст, пояснение или комментарий к блоку кода, чтобы поместить его в контекст.
Элиша Сено
Я даю объяснение. Спасибо @ElishaSenoo
Kinowe