Django风格:长查询?

Django风格:长查询?,django,coding-style,Django,Coding Style,我有一些相当长的(~150个字符)django查询。将它们拆分为多行的首选方式是什么 例如(不,不是我的真实代码): 编辑:更改示例,因为人们关注的是重复筛选,而不是查询的长度: person = models.UzbekistaniCitizen.objects.filter(occupation__income__taxable__gte=40000).exclude(face__eyes__color=blue).order_by('height').select_related('sib

我有一些相当长的(~150个字符)django查询。将它们拆分为多行的首选方式是什么

例如(不,不是我的真实代码):

编辑:更改示例,因为人们关注的是重复筛选,而不是查询的长度:

person = models.UzbekistaniCitizen.objects.filter(occupation__income__taxable__gte=40000).exclude(face__eyes__color=blue).order_by('height').select_related('siblings', 'children')
以下是我能想到的两种方法:

  • 使用反斜杠作为换行符:

    person = models.UzbekistaniCitizen.objects.\
                              filter(occupation__income__taxable__gte=40000).\
                              exclude(face__eyes__color=blue).\
                              order_by('height').\
                              select_related('siblings', 'children')
    
  • 在新行中重新应用过滤器:

    person = models.UzbekistaniCitizen.objects
    person = person.(occupation__income__taxable__gte=40000)
    person = person.exclude(face__eyes__color=blue)
    person = person.order_by('height')
    person = person.select_related('siblings', 'children')
    

  • 我首先想到的是,在这种情况下,更常见的是导入类,而不是模块:

    from models import UzbekistaniCitizen
    
    person = UzbekistanCitizen.objects ...
    

    取决于如果你经常使用这种过滤,你可能会考虑制作自己的习惯,所以它采用以下形式:

    #uses myfilter
    person = UzbekistaniCitizen.objects.myfilter(hair__color=brown,
                                                eye__color= blue,
                                                height__gt= 56,
                                                ...
                                                ...
                                                )
    
    或者其他对你来说更方便的事情

    注意:编辑后,使用管理器仍然适用。myfilter方法不必模仿filter函数,通过管理器,您可以做更多工作:

    person = UzbekistaniCitizen.males.hair("brown").eyes("blue").income(50000)
    
    这在很大程度上取决于您计划如何使用它,我不会仅仅为了缩短查询而设置自定义管理器

    在您上面提到的两个选项中,我更喜欢变体#1。我个人认为它更具可读性,只要看一眼就知道发生了什么#我的眼睛需要做更多的工作来找到被调用的相关方法,以了解实际发生的情况

    django在中使用了变量编号#3:

    虽然#3符合

    包装长行的首选方法是使用Python的 括号、括号和大括号内的行继续。排长队可能会很困难 通过将表达式括在括号中而在多行上断开。这些 应优先于使用反斜杠作为行延续


    。。。我个人不喜欢在python中使用这样的挂括号,但随着风格的决定:使用您觉得更合适的,只要可读性和一致性。

    我不确定您这样做是否出于说明目的,但基于您的示例,删除对
    filter
    的所有附加调用,只调用一个
    filter
    。当一个
    过滤器有很多参数时,我也倾向于使用一个可以更自然地跨行分布的字典:

    person = UzbekistaniCitizen.objects.filter(**{
        'hair__color': 'brown',
        'eye__color': 'blue',
        'height__gt': 56,
        'age__lte': 30,
        'job__income__taxable__gt': 40000,
    }).select_related()
    

    FWIW:如果您需要动态地修改
    过滤器的参数,这也是一种方便的方法。只需创建一个参数字典,就可以根据代码中的逻辑在字典中追加/更改/删除项。然后,您最终将其用于
    过滤器
    MyModel.objects.filter(**my_dict)

    您可以在整个rhs周围使用括号来获得隐含的行延续:

    person = (models.UzbekistaniCitizen
                    .objects
                    .filter(occupation__income__taxable__gte=40000)
                    .exclude(face__eyes__color=blue)
                    .order_by('height')
                    .select_related('siblings', 'children'))
    
    我有很好的风格

    person = (
        models
        .UzbekistaniCitizen
        .objects
        .filter(occupation__income__taxable__gte=40000)
        .exclude(face__eyes__color=blue)
        .order_by('height')
        .select_related('siblings', 'children')
    )
    
    在这种样式中,最方便的是不必手动缩进,每行缩进数为4个空格

    以下缺点: 1.如果重命名变量person,则必须手动调整缩进。 2.如果型号名称很长,很难将每行限制在80个字符以下

    person = UzbekistaniCitizen.objects.myfilter(hair__color=brown,
                                                eye__color= blue,
                                                height__gt= 56,
                                                ...
                                                ...
                                                )
    
    我的风格还有其他方便:

    1.可以添加评论:

    person = (
        models
        .UzbekistaniCitizen
        .objects
        .filter(occupation__income__taxable__gte=40000)  # your comment
        .exclude(face__eyes__color=blue)
        .order_by('height')  # 2016-10-11 add
        .select_related('siblings', 'children')
    )
    
    2.易于调试,您可以轻松注释某些条件

    下面的代码可以正常工作。这在调试中非常有用,您可以逐行注释条件,而不是删除并重做它

    person = (
        models
        .UzbekistaniCitizen
        .objects
        # .filter(occupation__income__taxable__gte=40000)
        .exclude(face__eyes__color=blue)
        # .order_by('height')
        .select_related('siblings', 'children')
    )
    

    我不知道你能做到-非常有用!从来没用过这个!确实非常有用。我的选票上升了,虽然它不再回答这个问题。这是迄今为止最可读的。我只是在一些开源代码中看到了这一点。我不敢相信我已经写了多年python而不知道这一点。这种语法有什么缺点吗?没有。我暂时避免了它,因为我担心它会被解释为元组定义。实际上,这是一种毫无根据的恐惧,一个单位的tuple def必须有尾随逗号的原因变得更清楚了:(1,)而不是(1)。我出于同样的原因避免使用它,认为它会变成一个tuple。从来没有想过后面的逗号,这是一个非常好的答案。请参阅肖恩的答案,了解使用隐含行继续的更清晰的方法。最重要的是漂亮。:)在我看来,这是一种比其他款式好得多的款式。每行有任意数量的空白以保持内容对齐,这使得我的眼睛更难跟踪,因为它可能变化太大。
    person = (
        models
        .UzbekistaniCitizen
        .objects
        # .filter(occupation__income__taxable__gte=40000)
        .exclude(face__eyes__color=blue)
        # .order_by('height')
        .select_related('siblings', 'children')
    )