用Django优化查询

用Django优化查询,django,django-queryset,Django,Django Queryset,我的问题是: 我有一个persone模型,它可能有一次或多次通过personetravel旅行 在personetravel中,travel字段是TagWithValue s是类似于“1954-05-01”的“开始”日期 e是类似于“1999-05-01”的结束日期 travel是一个类似“法国巴黎”的字符串 所以我在做一个基本的“搜索”来过滤谁旅行过,什么时候旅行过 我是这样做的,因为我是django的初学者,我很确定它可以优化: 我检索所有TagWithValue中具有匹配值的pk 我检

我的问题是:

  • 我有一个
    persone
    模型,它可能有一次或多次通过
    personetravel
    旅行
  • personetravel
    中,
    travel
    字段是
    TagWithValue
  • s
    是类似于“1954-05-01”的“开始”日期
  • e
    是类似于“1999-05-01”的结束日期
  • travel
    是一个类似“法国巴黎”的字符串
所以我在做一个基本的“搜索”来过滤谁旅行过,什么时候旅行过

我是这样做的,因为我是django的初学者,我很确定它可以优化:

  • 我检索所有
    TagWithValue
    中具有匹配
    值的
    pk
  • 我检索所有的
    pk
    人员旅行
    ,其旅行与之前的pk匹配
  • 我检索与之前的
    PersonTravel
    pk匹配的所有
    Personne
  • 我只想返回一个这样的连接(这当然是不好的sql,但只是为了得到一个好主意):

    有没有一种方法可以用我下面的代码来优化这个和那个

    q = Q()
    if s:
        q = q & Q(date_start__gte=s)
    if e:
        q = q & Q(date_end__lte=e)
    retour = [a[0] for a in TagWithValue.objects.filter(
        type_tag__exact=BaseTag.TYPE_GOOGLEMAPS,
        value__exact=travel).values_list('pk')]
    retour = PersonneTravel.objects.filter(Q(travel__in=retour) & q)\
        .values_list('personne__pk')
    if len(retour):
        retour = Personne.objects.filter(pk__in=retour)
    

    我认为您可以使用django的
    \uuuu
    语法,而无需
    Q-objects

    query = Personne.objects.filter(personnetravel__travel__value__exact=travel,
                                    personnetravel__travel__type_tag__exact=BaseTag.TYPE_GOOGLEMAPS) 
    
    # because django querysets are lazy you can add the date filters now
    if s:
        query = query.filter(personnetravel__date_start__gte=s)
    if e:
        query = query.filter(personnetravel__date_end__lte=e)
    

    这里不需要使用
    Q()
    。使用
    flat=True
    values\u list()
    获取值列表,而不是值类型列表。使用Django模型的
    ForeignKey
    列可以进一步简化此解决方案

    key = {}
    if s:
        key['date_start__gte'] = s
    if e:
        key['date_end__lte'] = e
    key[travel__type_tag__exact] = BaseTag.TYPE_GOOGLEMAPS
    key[travel__value__exact] = travel
    
    retour = PersonneTravel.objects.filter(**key)\
        .values_list('personne__pk', flat=True)
    
    if len(retour):
        retour = Personne.objects.filter(pk__id__in=retour)
    
    related_name
    示例:假设
    related_personne
    分别是
    personetravel
    模型中
    persone
    的相关名称

    key = {}
    key['related_personne__travel__type_tag__exact'] = BaseTag.TYPE_GOOGLEMAPS
    key['related_personne__travel__value__exact'] = travel
    if s:
        key['related_personne__date_start__gte'] = s
    if e:
        key['related_personne__date_end__lte'] = e
    
    retour = Personne.objects.filter(**key)
    

    请张贴你的模型。如果你能提供模型信息,那就太好了。假设结构,我已经添加了答案。请
    接受
    向上投票
    如果我的答案解决了您的问题,请回答:)
    key = {}
    key['related_personne__travel__type_tag__exact'] = BaseTag.TYPE_GOOGLEMAPS
    key['related_personne__travel__value__exact'] = travel
    if s:
        key['related_personne__date_start__gte'] = s
    if e:
        key['related_personne__date_end__lte'] = e
    
    retour = Personne.objects.filter(**key)