使用foreignkeys过滤对象

时间:2016-11-17 04:23:25

标签: python django filter

所以我有一个表单,用户可以为Kid发布Parent详细信息,以表示其他模型。

我需要的是允许用户通过过滤相关对象Parent

来访问Kid个对象的列表

让我们说一个过滤器列出名为X名为Z的孩子的父对象,他们居住在Y城市并且没有名为X的孩子小于Z居住在Y城市。

models.py

class Parent(models.Model):
    title = models.CharField(max_length=250)


class Kid(models.Model):
    cities = (
        ('city1', city1),
        ('city2', city2)
    )
    family = models.ForeignKey(Parent)
    title = models.CharField(max_length=250)
    age = models.CharField(max_length=250)
    city = models.CharField(choices=cities)

任何想法如何做或在哪里寻找答案?

2 个答案:

答案 0 :(得分:1)

你可以用反向逻辑来做。首先,您需要将age更改为IntegerField,否则您将无法比较其值

class Kid(models.Model):
    family = models.ForeignKey(Parent)
    title = models.CharField(max_length=250)
    age = models.IntegerField()
    city = models.CharField(choices=cities)

然后,您可以过滤所有符合您的过滤器的孩子并让父母的ID在以后进行过滤

filter_ids = Kid.objects.filter(name=X, age__gte=Z, city=Y).values_list('parents_id', flat=True).distinct()
exclude_ids = Kid.objects.filter(name=X, age__lt=Z, city=Y).values_list('parents_id', flat=True).distinct()

parents = Parent.objects.filter(id__in=filter_ids).exclude(id__in=exclude_ids)

回答评论 你首先用这些孩子填满所有父母,然后排除有其他孩子的父母。

filter_ids = Kid.objects.filter(my_pattern).values_list('parents_id', flat=True).distinct()
exclude_ids = Kid.objects.exclude(my_pattern).values_list('parents_id', flat=True).distinct()

parents = Parent.objects.filter(id__in=filter_ids).exclude(id__in=exclude_ids)

答案 1 :(得分:0)

Related manager似乎是一个可行的选择。

  

Django提供了一种强大而直观的“跟随”关系的方式   在查找中,在后面自动为您处理SQL JOINs   场景。要跨越关系,只需使用相关的字段名称   模型中的字段,由双下划线分隔,直到您得到   到你想要的领域。

     

它也是倒退的。要引用“反向”关系,只需使用模型的小写名称。

parents = Parent.objects.filter(kid__name=X,kid__age__gte=Y,kid__city=Z)

PS:我还没有测试过这段代码。目的是就方法提出建议。

编辑1:解决注释中指出的排除异常。 Link to Django documentation. Refer to the note in this section

排除行为与过滤器不同。相关经理中的排除不使用条件组合而是排除两者。 Parent.objects.exclude(kid__name=X,kid__city=Z)将排除名称为X的孩子和来自城市Z的孩子,而不是名为X且来自城市Z的孩子

Django建议的方法是:

Parent.objects.exclude(kid__in=Kid.objects.filter(name=X,city=Z))