2016-12-28 10 views
0

私はDjango ModelAdminリストビューでget_querysetを最適化しました:これらの最適化は、私はget_object変更ビューのために必要であることと同じではありませんジャンゴModelAdminのGET_OBJECT最適化

  • .only('field1', 'field2',)
  • .select_related('rel1',)

  • .only('field1', 'field2', 'field3',)
  • .select_related('rel1__rel2', 'rel3',)
  • .prefetch_related(...)

シングは、get_queryset and get_object are coupledです:

class BaseModelAdmin(...): 

    ... 

    def get_object(self, request, object_id, from_field=None): 
     """ 
     Returns an instance matching the field and value provided, the primary 
     key is used if no field is provided. Returns ``None`` if no match is 
     found or the object_id fails validation. 
     """ 
     queryset = self.get_queryset(request) 
     model = queryset.model 
     field = model._meta.pk if from_field is None else model._meta.get_field(from_field) 
     try: 
      object_id = field.to_python(object_id) 
      return queryset.get(**{field.name: object_id}) 
     except (model.DoesNotExist, ValidationError, ValueError): 
      return None 

どのように私は/上記のすべてのボイラープレートをコピー&ペーストすることなく、get_querysetを上書きすることができますか?

+0

まさにあなたがここで達成しようとしているものは不明である私は、このような何かをするだろう。問題にあなたの可能な解決策を列挙する代わりに、あなたが問題自体を述べた方がずっと良いでしょう。 'get_queryset'であなたの最適化は正確に何ですか? 'get_object'で適用したい最適化とは何ですか? –

+0

@НазарТопольський質問を更新しました –

答えて

1

def get_queryset(self, request): 
    queryset = super().get_queryset(request) 
    if request.resolver_match.url_name.endswith('_change'): 
     # admin change view 
     queryset = queryset.only(
      'iso_code', 
      *get_translation_fields('name'), 
      'official_languages', 
      'active', 
      'currency_code', 
      'currency_symbol', 
     ) 
    else: 
     # admin change list 
     queryset = queryset.only(
      'iso_code', 
      'name', 
      'active', 
     ) 
    return queryset 
+0

別のアプローチは、[wrapt](https://github.com/GrahamDumpleton/wrapt)パッケージを使用することです。 –

1

あなたのユースケースはあまり一般的ではないので、get_objectを書き直すことなく、必要なものを達成するための賢明な方法はないと思います。私は良い妥協点を思わこの溶液で作ってみた

# A parameter with default False value shouldn't screw things up 
def get_queryset(request, for_object=False): 
    qs = super(YourModelAdmin, self).get_queryset(request) 
    if for_object: 
     qs = qs.select_related('rel1__rel2', 'rel3') 
     qs = .prefetch_related('rel4', 'rel5') 
     return qs.only('field1', 'field2', 'field3') 
    else: 
     qs = qs.select_related('rel1') 
     return qs.only('field1', 'field2') 

def get_object(self, request, object_id, from_field=None): 
    # Don't forget to add new param here 
    queryset = self.get_queryset_for_object(request, for_object=True) 
    model = queryset.model 
    field = model._meta.pk if from_field is None else model._meta.get_field(from_field) 
    try: 
     object_id = field.to_python(object_id) 
     return queryset.get(**{field.name: object_id}) 
    except (model.DoesNotExist, ValidationError, ValueError): 
     return None 
+0

私のユースケースはあまり一般的ではないとは言いません。それは私にとって最適化101です。 –

+1

私は、 'get_object'とリストビューのための異なるクエリセットはそれほど一般的ではないと言っていました。この声明に同意しないと、code.djangoproject.comで改善チケットを発行することもできます。これにより、将来的にいくらか簡単になります。 –