LoginSignup
10
13

More than 5 years have passed since last update.

Djangoでクエリに名前付けする

Last updated at Posted at 2015-03-13

課題

Railsにはscopeという機能があって、頻出のクエリに名前付けを行うことができます。

class Post < ActiveRecord::Base
  scope :published, -> { where(published: true) }
end

Post.published
# SELECT "posts".* FROM "posts" WHERE "posts"."published" = 1

同じようなことをDjangoでもやりたいな、と思ってやり方を調べました。

解決方法

カスタマイズしたQuerySetと、ModelManagerを使うと、実現できるようです。

from django.db import models

class PostQuerySet(models.QuerySet):
    def published(self):
        return self.filter(published=True)

    def latest(self):
        return self.order_by('-updated_at')

class PostManager(models.Manager):
    def get_queryset(self):
        return PostQuerySet(self.model, using=self._db)

class Post(models.Model):
    published = models.BooleanField()
    # 他いろんなフィールド...

    objects = PostManager() # custom managerを定義

使い方。

>>> Post.objects.all().published()
# SELECT "posts".* FROM "posts" WHERE "posts"."published" = 1 

以下のようにチェーンさせることもできました。

>>> Post.objects.all().published().latest()

objects.all() などをつかってQuerySetを生成しないと使えないのがちょっと微妙な気もしますが、Viewなどが読みやすく実装できるようになると思います。

10
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
13