2016-11-23 113 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對象在使用模式對象的模式項中。

整個想法是使過濾器動態並允許用戶自己製作過濾器。

幫助?

回答

3

可以替換這段代碼:只要你喜歡

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)) 

與循環在其中添加儘可能多的過濾器:

# 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的另一種方式,可以評估一個QuerySet ,例如使用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實例來指定名稱。或者-simpler-你可以改變你的PatternItem.name字段爲CharField並使用'Q(name__title = pt_item.name)'代替。 –