Django - 过滤外键属性

188

我尝试根据ForeignKey的特定字段的值,在Django中过滤表格。

例如,我有两个模型:

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

我想知道是否有一种方法可以在主查询中指定这种筛选方式?


1
我有点困惑,project__in=project_list 是否应该是 Project__in=project_list(大小写是否敏感),因为你在模型中赋值了 Project - Chau Loi
1
@ChauLoi,不要把它看作是模型的另一个字段。 - Michael Higgins
3个回答

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

1
谢谢, 我之前尝试过,但显然我忘记使用双下划线了。 - Fraser Graham
4
需要包含吗? - DeadDjangoDjoker
2
@DeadDjangoDjoker contains 描述了 Django ORM 生成的查询中所使用的比较类型,相应的 SQL 查询语句可能看起来像是 LIKE '%Foo%' - orangecaterpillar

26

自从queryset-refactor分支在1.0之前着陆以来,这已经成为可能。Ticket 4088揭示了这个问题。 这应该可以工作:

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

Django的一对多文档提供了此类示例以及其他使用Model API跟踪外键的示例。


1
这会不会对数据库造成两次访问?我应该使用select_related()来使其更加优化吗? - Fraser Graham
6
你可以添加 .query.as_sql() 来查看实际执行的 SQL 语句。 - fastmultiplication
Django文档的链接已经过时,跳转到一个“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”属性为当前student_user的subjectgrade实例来排除所有已经被当前学生用户注册的科目。
PS. 如果由于我的解释而无法理解,请提前道歉。这是我能提供的最好的解释。非常感谢。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接