Django与ForeignKey值完全匹配

时间:2018-01-13 10:30:54

标签: django django-models

class Sentence(Model):
    name = CharField()

class Tokens(Model):
   token = CharField()
   sentence = ForeignKey(Sentence, related_name='tokens')
  1. 我想实现两个案例:句子完全由三个组成 令牌['I', 'like', 'apples']。所以sentence.tokens.all()列表 正是['I', 'like', 'apples']

  2. 与上述相同,但包含令牌(句子的一部分)。

  3. Sentence.objects.annotate(n=Count('tokens',distinct=True)).filter(n=3).filter(tokens__name='I').filter(tokens__name='like').filter(tokens__name='apples')不起作用,因为它也匹配I I I

    有没有办法过滤ForeignKey中的确切值集?

2 个答案:

答案 0 :(得分:6)

啊,我现在更好地理解这个问题了。只需利用您和Jay的代码元素,以下可能是一种方法。可能不是很优雅。但似乎有效。

def get_sentences(my_tokens):
    counts = dict()
    for t in my_tokens:
        counts[t] = my_tokens.count(t)
    results = Sentence.objects
    for k, v in counts.iteritems():
        results = results.filter(tokens__token=k).annotate(n=Count('tokens',distinct=True)).filter(n__gte=v)
    return results

>>> from django.db.models import Count
>>> from my.models import Sentence, Tokens

>>> s1 = Sentence.objects.create(name="S1")
>>> t10 = Tokens.objects.create(token="I", sentence=s1)
>>> t20 = Tokens.objects.create(token="like", sentence=s1)
>>> t30 = Tokens.objects.create(token="apples", sentence=s1)

>>> s2 = Sentence.objects.create(name="S2")
>>> t11 = Tokens.objects.create(token="I", sentence=s2)
>>> t21 = Tokens.objects.create(token="like", sentence=s2)
>>> t31 = Tokens.objects.create(token="oranges", sentence=s2)

>>> s3 = Sentence.objects.create(name="S3")
>>> t31 = Tokens.objects.create(token="I", sentence=s3)
>>> t32 = Tokens.objects.create(token="I", sentence=s3)
>>> t33 = Tokens.objects.create(token="I", sentence=s3)

>>> my_toks = ("I", "like", "apples")
>>> sentences = get_sentences(my_toks)
>>> sentences[0].name
u'S1'

>>> my_toks = ("I", "I", "I")
>>> sentences = get_sentences(my_toks)
>>> sentences[0].name
u'S3'

为了确切参考,我的模型看起来像这样:

class Sentence(Model):
    name = models.CharField(max_length=16)

class Tokens(Model):
    token = models.CharField(max_length=16)
    sentence = models.ForeignKey(Sentence, related_name='tokens')

答案 1 :(得分:2)

您是否尝试获取包含每个搜索令牌的每个句子?

这样做的灵活(虽然可能是非最佳)方式可能是:

search_tokens = ('I', 'like', 'apples')
results = Sentence.objects

for token in search_tokens:
    results = results.filter(tokens__name=token)

results.distinct()

这相当于将过滤器链接在一起:

results = Sentence.objects.filter(tokens__name='I').filter(tokens__name='like').filter(tokens__name='apples').distinct()