这是模型
class Player(models.Model):
name = models.CharField()
class ShootingAttempt(models.Model):
player = models.ForeignKey(Player, related_name='shooting_attempts')
is_scored = models.BooleanField()
point = models.IntegerField(default=0)
created_at = models.DateTimeField(auto_add_now=True)
实施:
jordan = Player.objects.create(name='Michael Jordan')
attempt1 = ShootingAttempt(player=jordan, is_scored=False)
attempt2 = ShootingAttempt(player=jordan, is_scored=False)
attempt3 = ShootingAttempt(player=jordan, is_scored=True, point=3)
attempt4 = ShootingAttempt(player=jordan, is_scored=False)
attempt5 = ShootingAttempt(player=jordan, is_scored=True, point=3)
attempt6 = ShootingAttempt(player=jordan, is_scored=True, point=3)
现在,如果给定的 ShootingAttempt ,其中pk = 5假定为名为is_scored=False
的玩家,则我如何查询之前的Micheal Jordan
?这将产生以下结果:[attempt4]
意味着乔丹在第5次成功挖掘3分之前有1次失误
如果给定的ShootingAttempt
pk=3
(尝试3),则会返回
[attempt1, attempt2]
意味着乔丹在成功挖掘前3分之前有2次失误
如果给出pk=6
,则不会返回任何内容,因为最后 is_scored=False
和{之间没有 is_scored=True
{1}}(尝试6)
意味着乔丹在挖掘另外3分之前没有错过
每次尝试都可能会错过,我希望每次成功尝试都能获得最后的失误。
有什么工作吗?
答案 0 :(得分:1)
这些是我更喜欢的步骤。
获取所需is_scored=True
ShootingAttempt
个实例的 id 。说id1
您可以使用is_scored=True
获取另一个ShootingAttempt
.filter(id__lt=id1).aggregate(id2=Max('id'))
个实例
这将返回 {id2:some_id} ,其中is_scored=True
且低于id1。
id2 = ShootingAttempt.objects.all().filter(id__lt=id1).aggregate(id2=Max('id'))['id2']
最后你可以 - .filter(id__gt=id2).filter(id__lte=id1)
返回带有False
s和最后True
的查询集。
答案 1 :(得分:0)
您可以在查询中使用const transformData=_=>_.map(_=>Object.assign(..._.map(([$,_])=>({[$]:_}))));
。
例如:
order_by
过滤器部分选择分数为“False”的对象,然后按降序排序,最后选择第一个元素(last_false = ShootingAttempt.objects.filter(is_scored=False).order_by('-created_at')[0]
)。
您还可以通过播放器以类似的方式嵌套过滤器:
[0]
编辑:
如果您希望所有以前尝试拥有该尝试的ID,您也可以last_false = ShootingAttempt.objects.filter(player=jordan).filter(is_scored=False).order_by('-created_at')[0]
使用pk
进行过滤:
__lt
答案 2 :(得分:0)
解决问题。
attempts = ShootingAttempt.objects.filter(player=jordan)[:pk]
n = len(attempts)
actual_attempts = [] if attempts[n-1].is_scored == True else
[attempts[n-1]]
n -= 1
while n and attempts[n-1].is_scored == False:
actual_attempts.append(attempts[n-1])
n -= 1
actual_attempts = actual_attempts[::-1]