2014-11-24 82 views
1

语境追加过滤器Django模型

嗨,

所以我们可以说我有两个型号:属性一个多对多的关系连接(一个人可以有很多属性,一个属性可以被许多人共享)

class Attribute(models.model): 
    attribute_name = models.CharField(max_length=100) 
    attribute_type = models.CharField(max_length=1) 

class Person(models.model): 
    article_name = models.CharField(max_length=100) 
    attributes = models.ManyToManyField(Attribute) 
  • 属性可以是头发颜色,位置,大学学位等。
  • 因此,例如,属性可能具有'计算机科学'的'attribute_name'和'D'(度数)的'attribute_type'。
  • 另一个例子是'伦敦','L'。

的问题

在这个网页上,用户可以通过属性选择的人。例如,他们可能希望看到所有居住在伦敦的人以及历史和生物学(都与人际关系)都有学位的人。

我明白,这可能在以下(减免清晰度)表示:

Person.objects 
.filter(attributes__attribute_name='London', attributes__attribute_type='L') 
.filter(attributes__attribute_name='History', attributes__attribute_type='D') 
.filter(attributes__attribute_name='Biology', attributes__attribute_type='D') 

然而,用户同样可以要求谁拥有四种不同程度的用户。关键是,我们不知道用户在搜索功能中要求多少属性。

问题

  • 因此,这将是追加这些过滤器,如果我们不知道有多少,用户会要求什么类型的属性的最佳方式?
  • 像这样追加过滤器是最好的方法吗?

谢谢!

尼克

回答

2

你可以获取用户选择的所有属性,然后遍历:

# sel_att holds the user selected attributes. 

result = Person.objects.all() 

for att in sel_att: 
    result = result.filter(
     attributes__attribute_name=att.attribute_name, 
     attributes__attribute_type=att.attribute_type 
    ) 
+0

我认为这是你用这个数据设计做的最好的,但是在迭代sel_att列表之前,我会亲自用'result = Person.objects.all()'开始 - 更好的可读性IMO。对于OP - 如果您可以选择不同的数据模型,那么您可能会从中受益。谷歌的'实体属性值'进行一些讨论。 – 2014-11-24 22:23:50

+0

完美。我得到了这个工作!谢谢,Raydel。彼得,非常感谢小费 - 我会读! – 2014-11-24 22:34:27

0

使用Q模块进行复杂的查找。

例如:

from django.db.models import Q 
Person.objects.get(Q(attributes__attribute_name='London') | Q(attributes__attribute_name='History') 

在一个QuerySet一个|充当OR和,充当AND,非常符合市场预期。

chanining filters的问题是你只能实现它们之间的AND逻辑,对于一个复杂的AND,OR或NOT逻辑,Q会是更好的方法。

+0

我试过Q,但是这会告诉我所有的人都具有这些属性中的至少一个,而我想与人*所有*他们。其次,这个查询尤其不适用于&符号,不幸的是 - 当我用&符号尝试时,它不返回任何结果。 – 2014-11-24 22:12:06