根据相关对象过滤对象

时间:2016-11-17 06:09:07

标签: python django filter

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

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

来访问Kid个对象的列表

让我们说一个过滤器列出名为X年龄小于Z的孩子的父对象居住在Y城市,并且没有名为X的孩子小于Z {1}}住在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)

Views.py

def index(request):
    my_pattern = (
    (name=samy, age_lt=15, city=paris),
    )
    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)
    template = 'index.html'
    context = {'parents': parents}
    return render(request, template, context)

如views.py显示我将模式列为元组但不起作用!

我也想知道这是否是django Q对象的方式,除了在开头添加Q!

1 个答案:

答案 0 :(得分:0)

my_pattern应为字典,您需要在过滤器中使用**解包并排除。

def index(request):
    my_pattern = {'name': 'samy', 'age__lt': 15, 'city': 'paris'}
    filter_ids = Kid.objects.filter(**my_pattern).values_list('family_id', flat=True).distinct()
    exclude_ids = Kid.objects.exclude(**my_pattern).values_list('family_id', flat=True).distinct()
    parents = Parent.objects.filter(id__in=filter_ids).exclude(id__in=exclude_ids)
    template = 'index.html'
    context = {'parents': parents}
    return render(request, template, context)

如果你有多种模式,那么你需要使用Q个对象

import operator
from functools import reduce

def index(request):
    patterns = [
        {'name': 'samy', 'age__lt': 15, 'city': 'paris'},
        {'name': 'sally', 'age__gt': 20, 'city': 'london'}
    ]
    filter_q = reduce(operator.or_, map(lambda p: Q(**p), patterns))
    filter_ids = Kid.objects.filter(filter_q).values_list('family_id', flat=True).distinct()
    exclude_ids = Kid.objects.exclude(filter_q).values_list('family_id', flat=True).distinct()
    parents = Parent.objects.filter(id__in=filter_ids).exclude(id__in=exclude_ids)
    template = 'index.html'
    context = {'parents': parents}
    return render(request, template, context)