在Django中选择一个随机的ForeignKey

时间:2018-02-18 22:40:55

标签: django

想象一下,我有一个模型Monster和模型Fight,可以将用户分配给怪物。

class Fight(models.Model):
    fight_user = models.OneToOneField(User, on_delete=models.CASCADE)
    fight_enemy = models.ForeignKey(Monster, on_delete=models.CASCADE)

现在,如果用户(fight_user)没有与之关联的Fight实例,我想通过从Monster模型中随机选择一个实例来创建一个实例。< / p>

我该怎么做?

1 个答案:

答案 0 :(得分:0)

需要考虑的一些事项:

  1. 您是否希望这是一个启动一次以填充每个没有关联Fight实例的用户的进程?这可以在POST视图中完成。
  2. 不同的用户可以对抗同一个怪物,还是每个人都面对不同的怪物?在后一种情况下,如果没有足够的怪物可以发生什么?
  3. 在对您的问题的评论中,用户@bonidjukic链接了this post,但这仅适用于您想要随机拉出一个怪物。

    由于你会在没有战斗的情况下为所有用户分配一个随机怪物,我建议将所有怪物加载到一个列表中并从那里随机选择,直到所有用户都有战斗。请参阅下面的代码:

    import random
    from django.contrib.auth.models import User
    from .models import Fight, Monster
    
    
    def get_available_monsters(only_one_fight_per_monster):
        monster_qs = Monster.objects.all()
    
        if only_one_fight_per_monster:
            # only monster that do NOT have a fight already
            monster_qs = monster_qs.filter(fight__isnull=True)
    
        # convert to list
        # if you have many thousand monsters, this approach might not be the best
        return list(monster_qs)
    
    
    def create_fights(only_one_fight_per_monster):
        monster_list = get_available_monsters(only_one_fight_per_monster)
    
        # all users without a fight
        for usr in User.objects.filter(fight__isnull=True):
            i = random.randrange(0, len(monster_list))
    
            f = Fight()
            f.fight_user = usr
            f.fight_enemy = monster_list[i]
            f.save()
    
            if only_one_fight_per_monster:
                monster_list.pop(i)
    

    如果每个用户与不同的怪物战斗,那么如果用户数量超过怪物,则可能会失败。

    请告诉我这是否对您有所帮助,即使答案有点迟了。