每个用户点击django网站时显示不同的横幅

时间:2012-01-17 12:17:37

标签: django cookies

我有横幅模型

class SiteBanner( models.Model ):
   banner = models.FileField( storage=s3_storage, upload_to = 'banners/', null=True, blank=True )
   order = models.PositiveIntegerField ( default=0 ) 
   default = models.BooleanField ( default = False )

我想在每个用户点击或每个网站页面上显示不同的横幅。当我为横幅设置defaultTrue时,它将被禁用,然后此横幅将显示在每个页面上。 这可能吗?如果是,那将是一个优雅的解决方案? cookies是否有助于实现这一目标?

2 个答案:

答案 0 :(得分:2)

首先,您需要一个上下文处理器来为您获取横幅:

# your_app/context_processors.py

def get_banner(request):
    seen_banners = request.session.get('seen_banners', [])
    try:
        banner = SiteBanner.objects.exclude(pk__in=seen_banners, default=False).order_by('order')[0]
    except IndexError:
        if seen_banners:
            del request.session['seen_banners']
            try:
                banner = SiteBanner.objects.exclude(default=False).order_by('order')[0]
            except IndexError:
                return {}
        else:
            return {}
    else:
        if seen_banners:
            request.session['seen_banners'].append(banner.pk)
            request.session.modified = True
        else:
            request.session['seen_banners'] = [banner.pk]
        return {'banner': banner}

将其与settings.py TEMPLATE_CONTEXT_PROCESSORS设置相关联。然后,在每个模板中,您将自动拥有一个banner变量,可用于访问要加载的横幅(假设至少有一个横幅可用)。

上下文处理器有点复杂,所以我应该引导您完成它。首先,它尝试从会话中检索“看到的”横幅列表。然后,这用于从查询集中排除这些横幅(因此同一用户不会再次获得相同的横幅)。如果没有至少一个可用横幅,则会出现IndexError,因此我们会抓住它。如果是因为用户已经看过它们,我们会杀死会话var并尝试再次获得横幅而不排除任何横幅。否则,实际上没有可用的横幅,所以我们只返回一个空的上下文。

如果我们能够获得横幅,那么我们将其id添加到会话var中,这样它就不会重复,然后我们返回包含横幅的上下文。

答案 1 :(得分:1)

(1)让每个页面都从显示横幅的模板继承。在此处了解模板继承:https://docs.djangoproject.com/en/dev/topics/templates/#template-inheritance

(2)使用上下文处理器选择横幅,并将其插入上下文中;也就是说,将其作为模板中的变量提供。在此处了解上下文处理器:https://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext

编写代码留给读者练习。