2016-07-22 18 views
2

自分自身にリンクされているForeignKeyを持つdjangoモデルがあるとすれば、グループ名でdjangoユーザのクエリーセットに注釈を付ける

from django.db.models import BooleanField 
from django.db.models import Func 


class IsNull(Func): 
    """ 
    See docs: https://docs.djangoproject.com/en/1.8/ref/models/database-functions/ 
    """ 
    template = '%(expressions)s IS NULL' 

    def __init__(self, *args, **kwargs): 
     kwargs['output_field'] = BooleanField() 
     super(IsNull, self).__init__(*args, **kwargs) 

は、だから私はこれを行うことができます:

queryset = DjangoModel.objects.all() 
queryset = queryset.annotate(**{'is_latest': IsNull('successor')}) 

と使用queryset.values() ..私は取得する場合

class DjangoModel(): 

    [...] 

    successor = models.ForeignKey('self', null=True) 

私はこのようなカスタムDjangoのデータベース関数を記述することができました
[{'pk': 1, is_latest': True}, {'pk': 2, 'is_latest': False}, ] 

wher e is_latest == Truesuccessorフィールドがオブジェクトの場合はNULLです。

今、私は似たようなことをしたいと思っていますが、どこから始めたらいいのですか?

バンドルdjango.contrib.auth.models.Userは私のプロジェクトのためにモデル

に多対多の関係を持っている、複数のユーザーグループタイプがあり、例えば顧客/マーケティング/金融など

私が何をしたいのか..注釈を付けていますUserクエリーセットis_FOOフィールドここで、FOOはグループ名です。私は、クエリセットに.values()を使用している場合などis_customerまたはis_marketing

だから、私はこのような何かを得る必要があります。

[{'pk': 1, 'is_customer': True, 'is_marketing': False }, {'pk': 1, 'is_customer': True, 'is_marketing': True }] 

グループ名はハードコーディングすることができ、例えば

queryset.annotate(**{'is_customer': IsGroupMember('customer')}) 

を私は助けを必要とIsGroupMemberデータベース機能を使用してください。

これは可能ですか?私を始めるためのヒントやヒント

本当にありがとうございます。多くのおかげで

答えて

1

私はDjangoの認証ユーザーモデル

from django.contrib.auth.models import User 

と私が興味グループ名を使用していることを考えると

:-)問題のための2つのソリューションを持っています:

CUSTOMER_GROUP_NAME = 'customer' 

ソリューション1からにトドルVelichkovによって示唆されているようにGoogleグループ。

下の彼の答えの

わずかに変更されたバージョン:元の答えに

from django.db.models.expressions import RawSQL 


def is_group_member(group_name): 
    return RawSQL("""EXISTS(
     SELECT 1 FROM `auth_group` 
     WHERE `auth_group`.`name` = %s 
      AND `auth_group`.`id` IN (
       SELECT `auth_user_groups`.`group_id` 
       FROM `auth_user_groups` 
       WHERE `auth_user_groups`.`user_id` = `auth_user`.`id` 
      ) 
    )""", (group_name,), output_field=BooleanField()) 


qs1 = User.objects.all().annotate(is_customer=is_group_member(CUSTOMER_GROUP_NAME)) 

リンク:https://groups.google.com/d/msg/django-users/BLCGZtUzEcY/w5w87frbBgAJ


私はいくつかのより多くの研究を行なったし、Djangoの条件式について学びました。

ドキュメント:https://docs.djangoproject.com/en/1.9/ref/models/conditional-expressions/

ソリューション2 - Djangoの表現を使用して

from django.contrib.auth.models import User 
from django.db.models import BooleanField 
from django.db.models import When, Case, Value 

query = When(groups__name__in=[CUSTOMER_GROUP_NAME, ], then=Value(1)) 
qs2 = User.objects.annotate(
    is_customer=Case(query, default=Value(0), output_field=BooleanField())) 

:-)私は、 "ソリューション2" は、クリーンで読みやすいと思います。だから私はそれを使用します:-)

関連する問題