在django中通过FK的FK获取相关对象(_set会起作用吗?)

Get related objects through FK of a FK in django (will a _set work?)

如果我有这样的模型结构:

class Camp(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=200, blank=True, null=True)
    reg_start = models.DateTimeField()
    reg_end = models.DateTimeField()

class Course(models.Model):
    camp = models.ForeignKey(Camp, on_delete=models.PROTECT)
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=500, blank=True, null=True)

class ClassDetail(models.Model):
    course = models.ForeignKey(Course, on_delete=models.PROTECT)
    seat_count = models.IntegerField()
    limit_registrations = models.BooleanField(default=False)

class Registration(models.Model):
    person = models.ForeignKey(User, on_delete=models.PROTECT)
    class_detail = models.ForeignKey(CourseDetail, on_delete=models.PROTECT)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

如果我的用户拥有(可能)多个 Registrations,是否有快速简便的方法来获取这些营地的 ID 列表?

这是我目前拥有的(它正在运行,但我正在尝试查看是否可以消除列表理解)

        registration_queryset = Registration.objects.filter(
            person__id=user_id
        )

        camps_to_exclude = [
            x.course_detail.course.camp.id for x in registration_queryset
        ]
        # camp_list is an already existing queryset of camps
        camp_list = camp_list.exclude(
            id__in=camps_to_exclude,
        )

这是一种选择。只要它们是查询集,django 就会将它们缩减为单个查询。您可以随时使用 print(queryset.query).

检查查询
camp_list.exclude(
    id__in=registration_queryset.values_list('course_detail__course__camp__id', flat=True),
)

或者你可以这样做:

camp_list.exclude(
    course_set__classdetail_set__registration_set__person_id=user_id
).distinct()

distinct 是必需的,因为您要跨越一对反向外键。