如果所有外键都在字典

时间:2016-11-19 14:48:22

标签: python django dictionary filter foreign-keys

我需要的是允许用户通过过滤相关对象“孩子”来访问Parent个对象的列表

我们有一个有100个孩子的字典。和平均约有5个孩子的父母 如果1个父对象中的孩子都在字典中,我希望它们被列出。 但并非所有100个孩子都必须与父对象相关。

例如,如果父母有4个孩子在字典中而1则不在字典中。然后不要包括它们。

我有以下代码

models.py

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


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

Views.py

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)

所以使用上面显示的当前视图功能。所有的孩子都必须在父母身边!

请帮忙!

1 个答案:

答案 0 :(得分:0)

如果我理解你的问题,我会怎么做。

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))      
    qs = Kid.objects.filter(filter_q).values_list('id', 'family_id') 
    family_ids = set()
    child_ids = list()
    for child_id, family_id in qs:
        family_ids.add(family_id)
        child_ids.append(child_id)        
    # At this point we have the complete list of matching Kid(s) in child_ids
    # . . . and we have a list of all family IDs in which those Kid(s) exist
    # Now we look for incomplete families, 
    # i.e., families that were part of the first query, 
    # but have Kid(s) that are not in our complete list 
    # of matching kids.
    incomplete_family_ids = set(Kid.objects.exclude(id__in=child_ids).filter(family_id__in=family_ids).values_list('family_id', flat=True).distinct())
    # Now we find the set complement to make life on the database a little easier.
    complete_family_ids = family_ids - incomplete_family_ids
    parents = Parent.objects.filter(id__in=complete_family_ids)
    template = 'index.html'
    context = {'parents': parents}
    return render(request, template, context)