Django
カスタムマネージャとクエリセット
サーチ…
Querysetsと `as_manager`メソッドを使用して基本マネージャを定義する
Django mangerは、djangoモデルがデータベースに問い合わせるインターフェイスです。ほとんどのdjangoクエリで使用されるobjects
フィールドは、実際にdjangoによって作成されたデフォルトのマネージャです(これは、カスタムマネージャを定義しない場合にのみ作成されます)。
なぜカスタムマネージャー/クエリーセットを定義するのでしょうか?
私たちのコードベース全体に共通のクエリを書くのを避け、代わりに覚えやすい抽象を使ってそれらを参照する。例:どのバージョンが読みやすいかを自分で決めます:
- すべてのアクティブなユーザーのみを取得する:
User.objects.filter(is_active=True)
vsUser.manager.active()
-
User.objects.filter(is_active=True).filter(is_doctor=True).filter(specialization='Dermatology')
vsUser.manager.doctors.with_specialization('Dermatology')
もう一つのメリットは、明日、我々はすべてのpsychologists
がdermatologists
であると判断した場合、私たちはマネージャーで簡単にクエリーを修正し、それを完了することができるということです。
以下は、カスタム作成の一例である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
はもう定義されません。
すべてのクエリに対してselect_related
外部キーを持つモデル
これらのモデルで作業します:
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')