2017-08-09 10 views
0

現在、アノテーションと含まれている演算子を使用したdjangoクエリーセットの動作に苦しんでいます。そして&牽引クエリーセットを結合した後にクエリーセット注釈を保持する

私はこのようなモデルがあります:私は単純にincluded_excluded機能は次のように、自分の注釈との両方クエリセットの参加クエリセットを返すことが期待

class Property(models.Model): 
    value = models.IntegerField(null=True) 

    obj = PropertyManager() 

class Profile(models.Model): 
    name = models.CharField() 
    values = models.ManyToManyField(Property) 

class PropertyManager(models.Manager): 
    def included(self, profile): 
     super(PropertyManager, self).filter(Q(property__profile=profile)).annotate(included_value=Value('true', output_field=CharField())) 

    def excluded(self, profile): 
     super(PropertyManager, self).filter(~Q(property__profile=profile)).annotate(included_value=Value('false', output_field=CharField())) 

    def included_excluded(self, profile): 
     return (self.excluded(profile) | self.included(profile)).distinct() 

property_id | included_value 
------------|--------------- 
      1 | true 
      2 | false 

それが判明し私の例で注釈が上書きされていることを確認してください:

j = Profile.objects.get(id=1) 
exc = Property.obj.excluded(profile=j) 
inc = Property.obj.included(profile=j) 
all = Property.obj.included_excluded(profile=j) 

len(inc) => 14 
len(exc) => 17 
len(all) => 31 

all.values_list("included_value") => <QuerySet [('false',)]> 
exc.values_list("included_value") => <QuerySet [('false',)]> 
inc.values_list("included_value") => <QuerySet [('true',)]> 

allは明らかに、私が期待したように注釈の正しい値のすべてを持っていません。

上向きにあなたはこのようにそれを行うことができる2つのクエリセットに参加して、私はDjangoの1.8から以前

答えて

0

をした注釈を維持する方法があるかどうだから私は、思ったんだけど:

from django.db import models 
from django.db.models import Case, When 

def included_excluded(self, profile): 
    return super(PropertyManager, self).annotate(
     included_value=Case(
      When(property__profile=profile, then='true'), 
      default='false', output_field=models.CharField() 
     ) 
    ) 

あなたの場合それらを別々に必要とする場合は、後でこのクエリーセットをフィルタリングすることができます:PropertyManager().included_excluded(profile).filter(included_value='true')

関連する問題