假设我有一个从椰子到燕子的外来钥匙(也就是说,一只燕子已携带许多椰子,但每只椰子只携带一只燕子)。现在让我们说我有一个从husk_segment到Coconut的ForeignKey。
现在,我有一个husk_segments列表,我想知道是否所有这些都被特定的燕子抓住了。
我可以使用swallow.objects.filter(coconuts_carried__husk_sements__in = husk_segment_list)来显示此燕子已经抓住了列表中的至少一个外壳片段。现在,我怎样才能证明燕子所携带的每个稻壳都在这个清单中?
答案 0 :(得分:2)
请参阅the docs on queries spanning multi-valued relationships - 您应该对过滤器调用进行链接。
一个简单的方法就是
queryset = Swallow.objects.all()
for coconut in coconuts:
queryset = queryset.filter(coconuts_carried=coconut)
使用reduce
在一行中执行此操作的一种奇特方法是
reduce(lambda q, c: q.filter(coconuts_carried=c), coconuts, Swallow.objects.all())
答案 1 :(得分:2)
我可以有swallow.objects.filter(coconuts_carried__husk_sements__in = husk_segment_list)表明这只燕子已经抓住了至少一只 列表中的稻壳段。
不,这是错误的,这会给你一个燕子列表,它们至少携带了一个来自* husk_segment_list *的一个稻壳段。
如果我理解正确,我们正在谈论检查特定的燕子。
所以,根据你的描述,我猜你的模型看起来像这样:
class Swallow(models.Model):
name = models.CharField(max_length=100)
class Coconut(models.Model):
swallow = models.ForeignKey(Swallow, related_name='coconuts_carried')
class HuskSegment(models.Model):
coconut = models.ForeignKey(Coconut, related_name='husk_segments')
如果您已经拥有了husk细分列表,则需要再次检查吞咽细分,您无需在查询中解决它。获取燕子的片段并检查它是否是您的果壳片段列表的超集。
所以我们有:
#husk_segment_list = [<object: HuskSegment>, <object: HuskSegment>, <object: HuskSegment>...]
husk_segments_set = set((husk.pk for husk in husk_segment_list))
whitey = Swallow.object.get(name='Neochelidon tibialis')
wh_segments_set = set((value[0] for value in HuskSegment.objects.filter(coconut__in=whitey.coconuts_carried.all()).values_list('id')))
whitey_has_carried_all = wh_segments_set.issuperset(husk_segments_set)
答案 2 :(得分:0)
如果我正确地理解了你改变的问题,你应该能够将燕子的椰子莴苣与已经携带的椰子列表进行比较。
请参阅docs
我不完全确定这是你想要的 - 我想这取决于你是否知道你想要事先检查哪个燕子,或者你想要检查所有燕子 - 在这种情况下可能会有更好的溶液