我有这个模板标签,它最终会返回一个“事件”广告列表(检查事件字段是否为 True ,然后使用查询集从事件中提取广告)

@register.assignment_tag
def get_current_campaigns(amount):

    # Get all the campaigns that are active
    current_campaigns = Campaign.objects.filter(active=True)

    current_campaigns_count = current_campaigns.count()

    # To avoid the list index being out of range and throwing an IndexError
    # We reduce the amount to match the amount of rows in the model if the
    # amount of rows is less than the amount being requested.
    if amount > current_campaigns_count:
        amount = current_campaigns_count

    # Select active campaigns randomly
    random_camps = []
    for i in range(amount):
        random_camps.append(random.choice(current_campaigns))

    # prepare all the ads to return
    output = []
    for campaign in random_camps:
        # get all the ads that a campaign has
        ads = campaign.advertisement_set.all()
        # now select one randomly
        ad = random.choice(ads)
        # hand it to output
        output.append(ad)
        # mark that this campaign has been seen
        campaign.impressions = F('impressions') + 1
        campaign.save()
        # checks and sets if the campaign is still active
        campaign.check_active()

    return output

这是与之配套的模型:
class Campaign(models.Model):
    ''' Represents an Advertisement Campaign '''
    title = models.CharField(max_length=50, blank=True, verbose_name='Campaign Title')
    impressions = models.IntegerField()
    impression_limit = models.IntegerField()
    created = models.DateTimeField(auto_now_add=True)
    active = models.BooleanField(default=False)

    def check_active(self):
        ''' Checks if the Campaign is currently active '''
        if self.impressions >= self.impression_limit:
            self.active = False
            self.save()

奇怪的一点:每次我访问广告所在的页面,然后在管理员中检查它时,对象印象数都会增加 2(应该是 1)并被标记为 False,即使这个 if self.impressions >= self.impression_limit 不是真的,无论如何,它仍然以某种方式将事件字段更改为 False

任何线索为什么会发生这种奇怪的行为?如果需要,我可以提供更多信息。

最佳答案

random.choice 不保证产生非重复项。

import random

random_camps = random.sample(current_campaigns, amount)

是去这里的方式。

更新
如果您担心速度,this question 可以解决 postgres 中的快速随机行选择问题。

关于python - F() 用 Django 表达奇怪的行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30416888/

10-12 23:47