2017-02-28 17 views
0

私は、既知のルックアップタイプを使ってモデルに問い合わせるためにaを書きました。入力タイプが何であるかを示すフラグは、kwargsとして渡されます。 kwargルックアップは、以下のように、渡されたkwargsとともに説明されています。DRYに違反しないようにdjangoクエリを使用するリファクタリング方法?

  1. データベースハッシュオブジェクトの(ランダムないdb_hash=Trueと、インスタンスに固有の)オブジェクトの
  2. 名前(「ジョン」又はname=Trueとして「サム」)
  3. ID。私が欲しい

    self.check_all_routes("Sam", "452", name=True) 
    

    、単にメソッドの呼び出しは次のようになり名例えば

(いずれかのフラグなしOBJS)

  • インスタンス(124、または134id=Trueなどをobj.ids) DRYに違反している間に発生している混乱を減らすための以下の方法をリファクタリングします。

    def check_all_routes(self, driver, route, **kwargs): 
        _hash = kwargs.get('db_hash') 
        _name = kwargs.get('name') 
        _id = kwargs.get('id') 
    
        if _hash: 
         return self.model.objects.filter(
          driver__db_hash=driver, 
          route__db_hash=route 
         ).prefetch_related().select_related().values_list('route_number') 
        if _name: 
         return self.model.objects.filter(
          driver__name=driver, 
          route__name=route 
         ).prefetch_related().select_related().values_list('route_number') 
        if _id: 
         return self.model.objects.filter(
          driver_id=driver, 
          route_id=route 
         ).prefetch_related().select_related().values_list('route_number') 
    
        return self.model.objects.filter(
         driver=driver, 
         route=route 
        ).prefetch_related().select_related().values_list('route_number') 
    

    DRYに違反しないようにするために行うことができます。

  • +0

    kwargsの1つのみがTrueになることはできますか? –

    答えて

    5

    あなたはこのような何かを行うことができます:

    def check_all_routes(self, driver, route, **kwargs): 
        queries = { 
         "db_hash": ['driver__db_hash', 'route__db_hash'], 
         "name": ['driver__name', 'route__name'], 
         "id": ['driver_id', 'route_id'], 
         "default": ['driver', 'route'] 
        } 
        arg = next((k for k, v in kwargs.items() if v), 'default') 
        params = queries[arg] 
        query = dict(zip(params, [driver, route])) 
        return self.model.objects.filter(**query).prefetch_related().select_related().values_list('route_number') 
    

    は、それは少しの魔法だが、最も重要な部分は、あなたがして** dictの拡張構文でfilterに渡す辞書を構築することです。

    は(私はあなたのクエリが正しいか分からない、注意してください。。これらのすべてのルートおよびドライバの両方が、それは必ずしも真実ではありませんように思える値を、一致していることを確認してください)

    +0

    クエリキーで 'ハッシュ'ではなく 'db_hash'にする必要があります。編集が小さすぎるため、あなたの答えを編集できません。 – erhesto

    +0

    ありがとうerhesto、修正済み。 –

    0

    あなたは勇気ある場合、あなたはあなたが行うことができ、そのフィルタのラッパー

    def check_all_routes(self, **kwargs): 
        return self.model.objects.filter(
         **kwargs 
        ).prefetch_related().select_related().values_list('route_number') 
    

    を作るので、代わりの

    self.check_all_routes("Sam", "452", name=True) 
    

    を渡すことができ

    self.check_all_routes(driver__name="Sam", route__name="452") 
    

    タイプを指定する必要はありません。これの利点は、タイプを混在させることができることです。

    self.check_all_routes(driver__name="Sam", route__db_hash="some%hash%string") 
    
    関連する問題