2013-10-02 40 views
0

我有以下Django模型:如何过滤ManyToManyField的记录?

class TopicLabel(models.Model): 
    name = models.CharField(max_length=256) 
    order = models.IntegerField(null=True, blank=True) 
    topics = models.ManyToManyField(Topic, through='TopicLabelConnection') 

class Topic(models.Model): 
    title = models.CharField(max_length=140) 
    visible = models.NullBooleanField(null=True, blank=True, default=False) 

    def __unicode__(self): 
     return self.title 
    class Meta: 
     verbose_name = _('topic') 
     verbose_name_plural = _('topics') 

class TopicLabelConnection(models.Model): 
    topicId = models.ForeignKey(Topic, related_name='connection_topic') 
    labelId = models.ForeignKey(TopicLabel, related_name='connection_label') 

    def __unicode__(self): 
     return self.labelId.name + '/' + self.topicId.title 

我想创建的TopicLabel的方法,这将返回我TopicLabel.topic集合中的所有题目,其中有Topic.visible = True

我想一个Django相当于下面的查询方案:

SELECT * 
FROM OPINIONS_TOPICLABELCONNECTION, OPINIONS_TOPIC 
WHERE (OPINIONS_TOPICLABELCONNECTION.topicId_id = OPINIONS_TOPIC.id) AND 
    (OPINIONS_TOPICLABELCONNECTION.labelId_id = X) AND 
    (OPINIONS_TOPIC.visible = 1) 

其中X是主题标志的主键。

我尝试以下方法定义,它们都失败:

1)

class TopicLabel(models.Model): 
    [...] 
    def getVisibleTopics(): 
     return topics.filter(connection_topic__visible=True) 

2)

class TopicLabel(models.Model): 
    [...] 
    def getVisibleTopics(): 
     return topics.filter(visible=True) 

3)

class TopicLabel(models.Model): 
    [...] 
    def getVisibleTopics(): 
     return Topic.objects.filter(connection_label__visible=True).filter(connection_label__id=self.id) 

4)

class TopicLabel(models.Model): 
    [...] 
    def getVisibleTopics(): 
     return Topic.objects.filter(connection_label__visible=True).filter(connection_label__id=self.id) 

5)

class TopicLabel(models.Model): 
    [...] 
    def getVisibleTopics(): 
     return topics.filter(connection_topicId__visible=True) 

什么是正确的代码?

回答

3

首先,您需要将self作为方法的第一个参数。然后过滤主题。试试这个:

​​

此外,是否有你通过表创建自定义的原因?它看起来并不像你正在向它添加任何额外的数据。