DjangoでDBビット単位のクエリを実行する方法は?

Source django bit-manipulation

Djangoを使用してDBでビット単位のクエリを実行するにはどうすればよいですか?
ドキュメントでそれについて何も見つかりませんでした。
クエリセットを取得してから、プログラムでフィルタリングする必要がありますか?

興味がある場合は、パフォーマンスを向上させるために、非常に大規模で複雑なクエリで IN()ステートメントの代わりにビット演算を使用します。
何百万ものアイテム(レコード)を含むDBがあります。一部のフィールドは、アイテムプロパティのバイナリ表現を使用します。
例: Color フィールドは複数の値を持つことができるため、次のように構成されます。
0001 - Red
0010 - Green
0100 - Blue
1000 - White

(これらはバイナリ値です)
したがって、アイテムの色が赤と青の場合、 Colorフィールドには0101が含まれます。
ユーザーがDBにクエリを実行するとき、ビット単位のORを使用して一致を検索します(非常に遅い IN()の代わりに)。
推奨答え
F objectsを使用して、データベースレベルのビット演算を実行できます。

フィールドが負でない場合は、条件field & mask > 0(field > 0) AND (field >= (field & mask))として書き直すことができることを意味します。 maskのすべてのビットが適用されるかどうかを確認する場合((field & mask) == mask)、各ビットの前の式を作成してから、sqlANDを介して条件をマージできます。それがどのように行われるかの例をご覧ください。 (カスタムQuerySetは便宜上のものです。古いdjangoバージョンを使用する場合は、has_one_ofhas_allを別々の関数またはクラスメソッドとして実装できます。より良いPathThroughManager)。 1 * Fは、ビット演算で括弧を強制する回避策であることに注意してください。そうしないと、django(バージョン1.5の場合)が不正なSQLを生成します(colors >= colors & mask、比較の優先度が高いため、TRUE & maskを意味します)
import operator
from django.db import models
from django.db.models import Q, F

_bit = lambda x: 2**(x-1)
RED = _bit(1)
GREEN = _bit(2)
BLUE = _bit(3)
WHITE = _bit(4)


class ItemColorsQuerySet(models.QuerySet):

    def has_one_of(self, colors):
        """
            Only those that has at least one of provided colors
        """
        return self.filter(
            colors__gt=0,
            # field value contains one of supplied color bits
            colors__lt=F('colors') + (1 * F('colors').bitand(reduce(operator.or_, colors, 0)))
        )

    def has_all(self, colors):
        """
            Has all provided colors (and probably others)
        """
        # filter conditions for all supplied colors: 
        # each one is "field value has bit that represents color"
        colors_q = map(lambda c: Q(colors__gte=1 * F('colors').bitand(c)), colors)
        # one complex Q object merged via sql AND:
        # colors>0 and all color-bit conditions
        filter_q = reduce(operator.and_, colors_q, Q(colors__gt=0))
        return self.filter(filter_q)


class Item(models.Model):

    name = models.CharField(max_length=100, unique=True)
    # can handle many colors using bitwise logic. Zero means no color is set.
    colors = models.PositiveIntegerField(default=0)

    objects = ItemColorsQuerySet.as_manager()
その他答え #1
postgres dbの場合、djangoormで.extra()paramsを使用できます。

例えば:
SomeModel.objects.extra(where=['brand_label & 3 = 3'])
その他答え #2
django-bitfieldを確認してください。PostgreSQLでもうまく機能します(おそらくMySQLでもうまく機能します)
その他答え #3
@Ivan Klassと同じ、

django orm Fbitandまたはbitorを使用できます。
# filter Red and Blue(0101)
Color.objects.annotate(
  color_filter=F('color').bitand(0101)
).filter(color_filter__gte=0101)

 # filter Red or Blue(0101)
Color.objects.annotate(
  color_filter=F('color').bitand(0101)
).filter(color_filter__gt=0)   

関連記事

エラーの修正方法:不明なタイプ名 ‘namespace’
char配列の一部を出力します
DjangoRestフレームワークでカスタムトークンモデルを使用する方法
Djangoでモデルオブジェクトを作成する最良の方法は何ですか?
Django SECRET_KEYはインスタンスごとですか、それともアプリごとですか?