1

continuing the Django polls tutorial, I want an entry (I called it numChoices) in the Poll model that automatically updates with the number of Choices associated with that Poll. How can I do that?

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    numChoices = models.IntegerField()
    def __unicode__(self):
        return self.question
    def was_published_recently(self):
        now=timezone.now()
        return now-datetime.timedelta(days=1) <= self.pub_date < now
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'

class Choice(models.Model):
    poll = models.ForeignKey(Poll)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    def __unicode__(self):
        return self.choice_text

Clarification, the ideal use case would be such that:

If i just want to list all the polls with the number of choices associated with each poll, it won't have to query the Choice table.

But every time i add a choice, the poll entry associated with that choice will update it's numChoices count

4

3 回答 3

2

你不想要那个。只需将其设为模型的属性即可。

class Poll(models.Model):
   ...
  @property
  def numChoices(self):
    return self.choice_set.count()
于 2013-07-24T07:56:27.463 回答
1

将这些信息存储在模型中是否非常重要?您只需执行以下操作即可获得模型的所有相关对象的计数:

count = poll_object.choice_set.count()

当您在两个模型之间有外键链接时,Django 会自动为您创建“_set”(在本例中为choice_set)管理器。默认情况下,相关模型的名称将是模型名称的压缩版本,因此模型 poll_choice 的默认相关名称将是“pollchoice_set”。您可以在定义 FK 字段时覆盖相关名称,例如

class Choice(models.Model):
    poll = models.ForeignKey(Poll, related_name="choices")

所以现在你会做

poll_object.choices.count()

获取相关选择对象的数量。

于 2013-07-24T07:58:40.900 回答
1

正如前面的答案中提到的,您可以简单地使用@property,但是每次需要选择计数时都会花费您额外的数据库命中。例如,如果您想在一个页面上显示所有民意调查,选择计数如下:

{% for poll in polls %}
    {{ poll.question }} - Choises: {{ poll.numChoices }}
{% endfor %}

它将为循环中的每个轮询命中数据库。因此,对于该简单操作,您将有 1 + COUNT(Polls.objects.all()) 查询。这就是为什么您可以在模型字段中存储选择计数并添加另一种方法来更新选择计数的原因:

class Poll(models.Model):
    choices_count = models.IntegerField()  # To store num of choices.        

    def update_choices_count(self):
        self.choices_count = self.choice_set.count()
        self.save()

创建民意调查并添加一些选项后,您可以触发 update_choices_count。这对于管理员在编辑投票时生成一些额外的 SQL 查询并不重要,但对于用户生成大量额外的数据库点击以查看投票列表至关重要。

于 2013-07-24T14:49:38.580 回答