2016-11-23 9 views
2

私は親、名前、およびキッドモデルを持っている:フィルタオブジェクト

models.py

class Parent(models.Model): 
    title = models.CharField(max_length=250) 
    address = models.CharField(max_length=250) 


class Name(models.Model): 
    title = models.CharField(max_length=250) 


class Kid(models.Model): 
    family = models.ForeignKey(Parent) 
    name = models.ForeignKey(Name) 
    age = models.IntegerField() 
    city = models.CharField(max_length=250) 

と私はキッドオブジェクト場合は、親オブジェクトを表示するビュー機能を持っています親に関連した辞書ですべてです:

views.py

def index(request): 
    patterns = [ 
     {'name__title': 'samy', 'age__lt': 15, 'city': 'paris'}, 
     {'name__title': 'sally', 'age__gt': 20, 'city': 'london'} 
    ] 
    filter_q = reduce(operator.or_, map(lambda p: Q(**p), patterns)) 
    qs = Kid.objects.filter(filter_q).values_list('id', 'family_id') 
    family_ids = set() 
    child_ids = list() 
    for child_id, family_id in qs: 
     family_ids.add(family_id) 
     child_ids.append(child_id) 
    incomplete_family_ids = set(Kid.objects.exclude(id__in=child_ids).filter(family_id__in=family_ids).values_list('family_id', flat=True).distinct()) 
    complete_family_ids = family_ids - incomplete_family_ids 
    parents = Parent.objects.filter(id__in=complete_family_ids) 
    template = 'index.html' 
    context = {'parents': parents} 
    return render(request, template, context) 

私は同じように、モデルオブジェクトとパターン辞書を置き換えたい場合:

class Pattern(models.Model): 
    title = models.CharField(max_length=250) 


class PatternItems(models.Model): 
    name = models.ForeignKey(Name) 
    age = models.integer() 
    city = models.CharField(max_length=250) 
    pattern = models.ForeignKey(Pattern) 

ので、代わりの辞書。私は、パターンオブジェクトを使用して、KidオブジェクトがすべてPatternItems内にある場合、Parentオブジェクトを表示するためにパターンモデルからパターンを選択することが可能かどうか疑問に思います。

全体的な考え方は、フィルタを動的にして、ユーザーが独自のフィルタを作成できるようにすることです。

ヘルプ?あなたが好きなようにあなたができるだけ多くのフィルタを追加するループで

patterns = [ 
    {'name__title': 'samy', 'age__lt': 15, 'city': 'paris'}, 
    {'name__title': 'sally', 'age__gt': 20, 'city': 'london'} 
] 
filter_q = reduce(operator.or_, map(lambda p: Q(**p), patterns)) 

:あなたは、コードのこの部分を置き換えることができます

答えて

3

# init patterns as a list of PatternItems 
patterns = [ PatternItem(name=Name(title='samy'), age=15, city='paris'), 
      PatternItem(name=Name(title='sally'), age=20, city='london'), 
      ] 
# iterate through the list normally 
filters = [] 
for pt_item in patterns: 
    filters.append(Q(name__title=pt_item.name.title) & 
        Q(age__lt=pt_item.age) & Q(city=pt_item.city)) 

filter_q = filters[0] 
for f in filters[1:]: 
    filter_q |= f 

patternsを得るための別の方法は、クエリセットを評価することができ、例えばfilter()を使用して:

# any_column__gte and value here are just examples 
patterns = PatternItem.objects.filter(any_column__gte=value) 
# iterate through the patterns using .all() 
filters = [] 
for pt_item in patterns.all(): 
    ... 

このアプローチの唯一の問題は、リスト内の各PatternItemのために同様の比較(すなわちage__lt)を使用しなければならないことです。

ご注意:私の代わりに減らす()関数のループを使用しています、それはので、ここではPython 3に

+0

ここでパターン名を指定しますか?上記のコードで – DjangoGuy

+0

@DjangoGuyを使用するには、PatternItem.nameを既存のNameインスタンスに設定して名前を指定します。代わりに、PatternItem.nameフィールドをCharFieldに変更し、代わりに 'Q(name__title = pt_item.name)'を使用することができます。 –

+0

私はそれに関連するPatternItemsのX番号を持つ '大人'というパターンを持っているとしましょう。あなたが書いたコードのどこに「大人」と書いていますか? – DjangoGuy

0

存在しないので、おそらく明確ではありませんでした私の質問のための答えです。 @Paoloステファンのコードは、私が必要としていたほど近いものでした。

view.py

patterns = PatternItems.objects.filter(pattern__title='adults') 
filters = [] 
for pt_item in patterns.all(): 
    filters.append(Q(name__title=pt_item.name.title) & 
        Q(age__lt=pt_item.age) & Q(city=pt_item.city)) 

filter_q = filters[0] 
for f in filters[1:]: 
    filter_q |= f 
qs = Kid.objects.filter(filter_q).values_list('id', 'family_id') 
family_ids = set() 
child_ids = list() 
for child_id, family_id in qs: 
    family_ids.add(family_id) 
    child_ids.append(child_id) 
incomplete_family_ids = set(Kid.objects.exclude(id__in=child_ids).filter(family_id__in=family_ids).values_list('family_id', flat=True).distinct()) 
complete_family_ids = family_ids - incomplete_family_ids 
parents = Parent.objects.filter(id__in=complete_family_ids) 
template = 'index.html' 
context = {'parents': parents} 
return render(request, template, context) 

唯一の違いは、次のとおり パターン= PatternItems.objects.filter(pattern__title = '大人')パターン必要「大人とpatternitemsをフィルタリング

'

関連する問題