简体   繁体   中英

Django queryset filter for backwards related fields

How can you filter a model based on a model that relates to it? Example below...this works, but I think this hits the DB twice and is pretty inelegant. Is there a way to do it directly with querysets? Maybe somehow with select_related() , but haven't been able to figure that one out. I want to return a QuerySet of Project .

from django.db import models

class Person(models.Model):
    pass

class Project(models.Model):
    pass

class Action(models.Model):
    person = models.ForeignKey(Person)
    project = models.ForeignKey(Project)

# Better way to do this?
def projects_by_person(person):
    actions = Action.objects.filter(person=person)
    project_ids = actions.values_list('project')
    return Project.objects.filter(id__in=project_ids)

Try this. I haven't tested it let me know if you have any issues

#Untested Code
Project.objects.filter(action__person = person)

Is it true that you have a many-to-many relation between Person and Project ? If so, you can simplify your setup like this:

class Person(models.Model):
    projects = models.ManyToManyField('Project')
    name = models.CharField(max_length=100)     # just an example

class Project(models.Model):
    # ... some fields here ...

You can then eg issue the following query to get all the projects from people who are called John:

Project.objects.filter(person_set__name="John")

The usage of select_related() can speed up the lookup a bit when you have lots of queries which follow relations between different database tables but you don't need it to accomplish what you want.

You can find my case at below:

There are teachers and courses. Teachers can have multiple course but course has done by only one teacher.

class Course(models.Model):
    teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
    -------

class Teacher(models.Model):
    name = models.CharField(max_length=50)
    ------

Inside the individual Teacher page I want to list all courses given by this individual teacher. You can find the related view function below.

def teacher(request, teacher_id):
teacher = get_object_or_404(Teacher, pk=teacher_id)
courses = Course.objects.filter(teacher = teacher)

context = {
    'teacher': teacher,
    'courses': courses
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM