bugfix> python > 投稿

問題:名前が付けられたカスタムクエリセットが1つだけのモデルのカスタムマネージャーを実装しました get_by_tag このように使用すると、正常に機能します。

ViewStatistic.objects.get_by_tag('some-tag-name').filter(user=user_id)

しかし、クエリの順序を次のように変更すると、次のようになります。

ViewStatistic.objects.filter(user=user_id).get_by_tag('some-tag-name')

それは動作しません!そして、このエラーを発生させます:

AttributeError: 'QuerySet' object has no attribute 'get_by_tag'

私は何かが足りないのですか?!どうすればこのような順序でこれを行うことができますか?

追伸:カスタムマネージャーは次のようなものです:

class MyCustomManager(models.Manager):
    def get_by_tag(self, tag_name):
        posts = Post.objects.filter(tags__pk=tag_name)
        return super().get_queryset().filter(post__pk__in=posts)

回答 2 件
  • クエリセットメソッドをマネージャの直後だけでなくクエリセットチェーン内で使用する場合は、マネージャに接続するカスタムQuerySetクラスのメソッドとして定義する必要があります。

    2つのソリューションがDjangoのドキュメントに記載されていますQuerySetメソッドを使用したマネージャーの作成

    共通部分-querysetメソッドを使用したカスタムQuerySetクラス

    class MyCustomQuerySet(models.QuerySet):
        def get_by_tag(self, tag_name):
            return self.filter(post__pk__in=Post.objects.filter(tags__pk=tag_name))
        # more possible queryset methods ...
    
    

    A)マネージャーにクエリセットメソッドのみがあり、他のカスタムメソッドがない場合
    次に、QuerySetから簡単に作成できます。

    class MyModel(models.Model):
        objects = MyCustomQuerySet.as_manager()
    
    

    B)マネージャーがクエリセットを返さない他のメソッドも必要とする場合:

    class MyCustomManager(models.Manager):
        ...  # other methods
    class MyModel(models.Model):
        objects = MyCustomManager.from_queryset(MyCustomQuerySet)()
    
    

  • あなたが言う時 ViewStatistic.objects のオブジェクトを返します <django.db.models.manager.Manager>

    あなたの場合、それはクラスを派生させたので MyCustomManager 基本クラスを持つ models.manager 、したがって、のオブジェクトを返します <your_app.models.MyCustomManager> 持っている get_by_tag 機能し、アクセスできます get_by_tag

    2番目のケースの場合 ViewStatistic.objects.filter 戻る django.db.models.query.QuerySet オブジェクトともちろん、名前の付いたメソッドはありません get_by_tag そのため、AttributeErrorが発生します。

    クエリセットに関連するもう1つのポイントは ザ・QuerySetを改良した結果は、それ自体がQuerySetです。、したがって、改良を連鎖させることが可能です。

    https://docs.djangoproject.com/en/3.0/topics/db/queries/#chaining-filters

    あなたの場合、get_by_tagはQuerySetをさらに返し、.filter()操作を実行しました。これは問題ありません。

    モデルマネージャーに関連するdjangoの公式ドキュメントリンクをたどり、詳細を問い合わせることができます。 https://docs.djangoproject.com/en/3.0/topics/db/queries/

あなたの答え