2012-01-19 6 views
0

私は近接検索で使用される地理的オブジェクトを持っています。そのオブジェクトは、さまざまなパスを介して異なるオブジェクトにキーイングされます。Django Queryset - 変数としての複雑な関係パラメータ?

例:他のオブジェクトに

radius_queryset = base_queryset.filter(
    user__profile__geo__lat__gte = bounding_box.lat_min, 
    user__profile__geo__lat__lte = bounding_box.lat_max, 
    user__profile__geo__lon__gte = bounding_box.lon_min, 
    user__profile__geo__lon__lte = bounding_box.lon_max, 

、その後:

radius_queryset = base_queryset.filter(
    blog__geo__lat__gte = bounding_box.lat_min, 
    blog__geo__lat__lte = bounding_box.lat_max, 
    blog__geo__lon__gte = bounding_box.lon_min, 
    blog__geo__lon__lte = bounding_box.lon_max, 
) 

これは、次の

blog.geo_object 
    user.profile.geo_object 
    group.event.geo_object 

今、私はこのような文字列のバウンディングボックスの検索を行います一般的な形式:

radius_queryset = base_queryset.filter(
    [lookup_path]__geo__lat__gte = bounding_box.lat_min, 
    [lookup_path]__geo__lat__lte = bounding_box.lat_max, 
    [lookup_path]__geo__lon__gte = bounding_box.lon_min, 
    [lookup_path]__geo__lon__lte = bounding_box.lon_max, 
) 
# where lookup_path = "blog" or "user__profile" in the two above examples 

カプセル化はメンテナンス性の良い友人であり、誤植(typo-bug)との闘いの仲間でもあります。

私の質問に:execとeval(ちょっと見苦しい)を使用するのに不足していますが、変数のサブインドにフィルタパラメータ名を取得する方法はありますか?私はここで何か簡単なものを逃している?

答えて

4

**kwargsです。

def generate_qs(lookup_path, bounding_box): 
    return base_queryset.filter(**{ 
     lookup_path + '__geo__lat__gte' : bounding_box.lat_min, 
     lookup_path + '__geo__lat__lte' : bounding_box.lat_max, 
     lookup_path + '__geo__lon__gte' : bounding_box.lon_min, 
     lookup_path + '__geo__lon__lte' : bounding_box.lon_max, 
    }) 

radius_queryset = generate_qs('blog', bounding_box) 
+0

1あなたはそれに私を打つが、私は私は=よりよいあると思うので) – cha0site

+0

私は** kwargsからのまわりで私の頭をラップするために、まだましたが、私はそれがどのように動作するかを確認することができます。ありがとう! – Ted

+1

@Ted、**辞書のキーと値のペアをキーワードと引数のペアに展開します。 'func(キーワード=引数)== func(** {キーワード:引数})' –

0

私はあなたのヘルパー関数に離れてこの意地の悪さを置くためにPythonの**kwargs構文を使用することができると思います。ような何か:

def helper(lookup_path, bounding_box): 
     return dict([ ("%s__geo__%s" % (lookup_path, lkup_left,), 
         getattr(bounding_box, lkup_right),) 
        for lkup_left, lkup_right in 
        (("lat__gte", "lat_min",), 
         ("lat__lte", "lat_max",), 
         ("lon__gte", "lon_min",), 
         ("lon__lte", "lon_max",), 
        ) ]) 

qs = base_queryset.filter(**helper(lookup_path, bounding_box)) 
関連する問題