【问题标题】:Filter objects if all its foreignkeys are in a dictionary如果对象的所有外键都在字典中,则过滤对象
【发布时间】:2016-11-21 09:07:08
【问题描述】:

我需要的是允许用户通过过滤他们的相关对象`Kid'来访问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)

所以上面显示了我当前的视图功能。所有的孩子都必须在一个父母中!!!

请帮忙!

【问题讨论】:

  • 有 100 个孩子的字典在哪里?
  • 在示例中不存在。我的意思是我想制作一个项目列表/字典,我希望这些项目被过滤
  • 我想那时我真的不明白你的问题,因为听起来你的问题表明你已经“有一本有 100 个孩子的字典”。对不起。祝你好运!
  • 我已经实际测试了你的代码,它非常适合我的问题

标签: python django dictionary filter foreign-keys


【解决方案1】:

如果我正确理解了您的问题,我会这样做。

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)    

【讨论】:

  • 只是为了详细说明。如果字段 'name' 是 Name 模型的外键怎么办?
  • 是的,但我们需要查看 Name 模型定义以确保我们匹配正确的过滤器。但本质上,您会将'name'in patterns 更改为'name__field_to_match'(例如,'name__first_name'
  • 类名(models.Model): title = models.CharField(max_length=250)
  • 然后将模式中的'name'改成'name__title'
猜你喜欢
  • 1970-01-01
  • 2019-09-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-21
  • 1970-01-01
  • 1970-01-01
  • 2022-11-22
  • 2020-05-03
相关资源
最近更新 更多