首页 > 解决方案 > 如何根据 Django 中的模型实例数填充 CreateView 字段

问题描述

我有一个梯子上的玩家模型。

class Player(models.Model):
    # Availability choice list
    available = 'AVL'
    injured = 'INJ'
    away = 'AWY'
    retired = 'RET'
    AVAILABILITY_CHOICES = [
        (available, 'available'),
        (injured, 'injured'),
        (away, 'out of town'),
        (retired, 'retired')
    ]

    # Player fields
    first = models.CharField('First Name', max_length=30)
    last = models.CharField('Last Name', max_length=30)
    cell = models.CharField('Cell Phone', max_length=12)
    email = models.EmailField('Email') # changed field type
    availability = models.CharField('Availability', choices = AVAILABILITY_CHOICES, \
                                     max_length = 15, default='AVL')
    ranking = models.IntegerField(default = 99)

我也在使用 CreateView 来创建一个新播放器。

class PlayerCreateView(CreateView):
    model =Player
    num_players = Player.objects.all().count()
    print('There are {} players'.format(num_players))
    context_object_name = 'player'
    fields = ['ranking', 'first', 'last', 'cell', 'email', 'availability']
    template_name = 'player_create.html'
    success_url = reverse_lazy('players')

我不敢相信我在问这个(对 Django 来说还是新手),但我还没有找到一种方法来预先填充玩家的排名字段。所以基本上我需要计算现有玩家的数量并填充排名字段。它不能基于ID,因为某些玩家可能已被删除。

在模型中,我尝试使用一个变量作为默认值,但 Django 非常适合。(NameError: name 'Player' is not defined) ...显然是因为你不能在 Player 的类定义中引用 Player。

必须有一种“djangonista”的方式来做这个简单的事情。

标签: pythondjangocountinstance

解决方案


好吧,您可以通过覆盖在创建视图中预填充表单get_initial

class PlayerCreateView(CreateView):
    model = Player
    # ...

    def get_initial(self):
        initial = super().get_initial()
        initial["ranking"] = Player.objects.count()  # whatever formula
        return initial
    

如果您想要模型中的动态默认值,您可以将可调用对象指定为默认值

def default_ranking():
    return Player.objects.count()

class Player(models.Model):
    ranking = models.IntegerField(default=default_ranking)  # no parentheses!

但是,这不会填充表单字段,但只有在没有排名值的情况下保存实例时才会生效。


推荐阅读