サーチ…


Querysetsと `as_manager`メソッドを使用して基本マネージャを定義する

Django mangerは、djangoモデルがデータベースに問い合わせるインターフェイスです。ほとんどのdjangoクエリで使用されるobjectsフィールドは、実際にdjangoによって作成されたデフォルトのマネージャです(これは、カスタムマネージャを定義しない場合にのみ作成されます)。

なぜカスタムマネージャー/クエリーセットを定義するのでしょうか?

私たちのコードベース全体に共通のクエリを書くのを避け、代わりに覚えやすい抽象を使ってそれらを参照する。例:どのバージョンが読みやすいかを自分で決めます:

  • すべてのアクティブなユーザーのみを取得する: User.objects.filter(is_active=True) vs User.manager.active()
  • User.objects.filter(is_active=True).filter(is_doctor=True).filter(specialization='Dermatology') vs User.manager.doctors.with_specialization('Dermatology')

もう一つのメリットは、明日、我々はすべてのpsychologistsdermatologistsであると判断した場合、私たちはマネージャーで簡単にクエリーを修正し、それを完了することができるということです。

以下は、カスタム作成の一例であるManager作成することによって定義されたQuerySetして使用してas_manager方法を。

from django.db.models.query import QuerySet

class ProfileQuerySet(QuerySet):
    def doctors(self):
        return self.filter(user_type="Doctor", user__is_active=True)

    def with_specializations(self, specialization):
        return self.filter(specializations=specialization)

    def users(self):
        return self.filter(user_type="Customer", user__is_active=True)

ProfileManager = ProfileQuerySet.as_manager

以下のようにモデルに追加します:

class Profile(models.Model):
    ...
    manager = ProfileManager()

:モデルでmanagerを定義すると、モデルのobjectsはもう定義されません。

外部キーを持つモデル

これらのモデルで作業します:

from django.db import models

class Book(models.Model):
 name= models.CharField(max_length=50)
 author = models.ForeignKey(Author)

class Author(models.Model):
 name = models.CharField(max_length=50)

book.author.name頻繁に(常に)アクセスすると仮定します

ビューで

私たちは毎回次のことを使うことができました。

books = Book.objects.select_related('author').all()

しかし、これはドライではありません。

カスタムマネージャー

class BookManager(models.Manager):

    def get_queryset(self):
        qs = super().get_queryset()
        return qs.select_related('author')

class Book(models.Model):
    ...
    objects = BookManager()

:python 2.xではsuperへの呼び出しを変更する必要があります

今私たちはビューで使用する必要があります

books = Book.objects.all()

テンプレート/ビューで追加の照会は行われません。

カスタムマネージャを定義する

非常にしばしば、 publishedフィールドのようなものを持つモデルを扱うことがあります。このような種類のフィールドは、オブジェクトを取得するときにほとんど常に使用されるため、次のような記述をします。

my_news = News.objects.filter(published=True)

あまりにも何度も。カスタムマネージャーを使用してこれらの状況に対処できるので、次のような記述ができます。

my_news = News.objects.published()

これは他の開発者よりも読みやすく、読みやすいです。

appディレクトリにファイルmanagers.pyを作成し、新しいmodels.Managerクラスを定義します:

from django.db import models


class NewsManager(models.Manager):

    def published(self, **kwargs):
        # the method accepts **kwargs, so that it is possible to filter
        # published news
        # i.e: News.objects.published(insertion_date__gte=datetime.now)
        return self.filter(published=True, **kwargs)

このクラスを使用するには、モデルクラスのobjectsプロパティを再定義しobjects

from django.db import models

# import the created manager
from .managers import NewsManager

class News(models.Model):
    """ News model
    """
    insertion_date = models.DateTimeField('insertion date', auto_now_add=True)
    title = models.CharField('title', max_length=255)
    # some other fields here
    published = models.BooleanField('published')

    # assign the manager class to the objects property
    objects = NewsManager()

今すぐ公開ニュースを次のように簡単に入手できます:

my_news = News.objects.published()

さらにフィルタリングを実行することもできます。

my_news = News.objects.published(title__icontains='meow')


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow