我们刚刚开始为基于Django的项目进行A / B测试。我是否可以获得有关此A / B测试的最佳实践或有用见解的一些信息。
理想情况下,每个新的测试页面都会使用单个参数进行区分(就像Gmail一样)。 mysite.com/?ui=2应该给出不同的页面。因此,对于每个视图,我需要编写一个装饰器来根据'ui'参数值加载不同的模板。而且我不想在装饰器中硬编码任何模板名称。那么urls.py url模式将如何?
答案 0 :(得分:95)
答案 1 :(得分:12)
Django lean是A / B测试的好选择
答案 2 :(得分:7)
如果你使用像你建议的GET参数(?ui=2
),那么你根本不需要触摸urls.py。你的装饰师可以检查request.GET['ui']
并找到它需要的东西。
为避免硬编码模板名称,也许您可以从视图函数中包装返回值?您可以返回(template_name, context)
的元组并让装饰器破坏模板名称,而不是返回render_to_response的输出。这样的事怎么样? 警告:我尚未测试此代码
def ab_test(view):
def wrapped_view(request, *args, **kwargs):
template_name, context = view(request, *args, **kwargs)
if 'ui' in request.GET:
template_name = '%s_%s' % (template_name, request.GET['ui'])
# ie, 'folder/template.html' becomes 'folder/template.html_2'
return render_to_response(template_name, context)
return wrapped_view
这是一个非常基本的例子,但我希望它可以解决这个问题。您可以修改有关响应的其他几个内容,例如向模板上下文添加信息。您可以使用这些上下文变量与您的网站分析集成,例如Google Analytics。
作为奖励,如果你决定停止使用GET参数并转移到基于cookie等的东西,你可以在将来重构这个装饰者。
更新如果您已经编写了大量视图,并且不想全部修改它们,则可以编写自己的render_to_response
版本。
def render_to_response(template_list, dictionary, context_instance, mimetype):
return (template_list, dictionary, context_instance, mimetype)
def ab_test(view):
from django.shortcuts import render_to_response as old_render_to_response
def wrapped_view(request, *args, **kwargs):
template_name, context, context_instance, mimetype = view(request, *args, **kwargs)
if 'ui' in request.GET:
template_name = '%s_%s' % (template_name, request.GET['ui'])
# ie, 'folder/template.html' becomes 'folder/template.html_2'
return old_render_to_response(template_name, context, context_instance=context_instance, mimetype=mimetype)
return wrapped_view
@ab_test
def my_legacy_view(request, param):
return render_to_response('mytemplate.html', {'param': param})
答案 3 :(得分:1)
Justin的回答是对的...我建议你投票给那个,因为他是第一个。如果您有多个需要此A / B调整的视图,他的方法特别有用。
但请注意,如果您只有少量视图,则不需要装饰器或urls.py的更改。如果您将urls.py文件保留原样...
(r'^foo/', my.view.here),
...您可以使用request.GET来确定所请求的视图变体:
def here(request):
variant = request.GET.get('ui', some_default)
如果您想避免为单个A / B / C / etc视图编写模板名称的硬编码,只需在模板命名方案中使它们成为惯例(正如Justin的方法也推荐):
def here(request):
variant = request.GET.get('ui', some_default)
template_name = 'heretemplates/page%s.html' % variant
try:
return render_to_response(template_name)
except TemplateDoesNotExist:
return render_to_response('oops.html')
答案 4 :(得分:1)
基于Justin Voss的代码:
def ab_test(force = None):
def _ab_test(view):
def wrapped_view(request, *args, **kwargs):
request, template_name, cont = view(request, *args, **kwargs)
if 'ui' in request.GET:
request.session['ui'] = request.GET['ui']
if 'ui' in request.session:
cont['ui'] = request.session['ui']
else:
if force is None:
cont['ui'] = '0'
else:
return redirect_to(request, force)
return direct_to_template(request, template_name, extra_context = cont)
return wrapped_view
return _ab_test
使用代码的示例函数:
@ab_test()
def index1(request):
return (request,'website/index.html', locals())
@ab_test('?ui=33')
def index2(request):
return (request,'website/index.html', locals())
这里发生了什么: 1.传递的UI参数存储在会话变量中 2.每次加载相同的模板,但上下文变量{{ui}}存储UI id(您可以使用它来修改模板) 3.如果用户进入没有?ui = xx的页面,那么在index2的情况下,他被重定向到'?ui = 33',在index1的情况下,UI变量被设置为0。
我使用3从主页面重定向到Google网站优化工具,后者又会使用正确的?ui参数重定向回主页面。
答案 5 :(得分:1)
这些答案似乎陈旧。如今,Google Analytics可能是大多数网站上最受欢迎且最好的免费选项。以下是将django与Google Analytics集成的一些资源:
<强>插件强>:
如何:
答案 6 :(得分:1)
Django-lean看起来很棒。我打算试着弄清楚它。我最终推出了自己的解决方案,这足以满足我的目标。我试图很好地打包它,让初学者使用起来很方便。这是超级基础,试一试:
答案 7 :(得分:0)
我为django编写了一个拆分测试示例,任何看这个的人都会觉得有用 -
https://github.com/DanAncona/django-mini-lean
喜欢听到你对此的看法,以及如何让它更有帮助!
答案 8 :(得分:0)
您还可以使用Google Optimize进行A / B测试。为此,您必须将Google Analytics(分析)添加到您的网站,然后在创建Google Optimize实验时,每个用户都会获得一个具有不同实验变体的Cookie(根据每个变体的权重)。然后,您可以从Cookie中提取变体并显示应用程序的各种版本。您可以使用以下代码段提取变体:
ga_exp = self.request.COOKIES.get("_gaexp")
parts = ga_exp.split(".")
experiments_part = ".".join(parts[2:])
experiments = experiments_part.split("!")
for experiment_str in experiments:
experiment_parts = experiment_str.split(".")
experiment_id = experiment_parts[0]
variation_id = int(experiment_parts[2])
experiment_variations[experiment_id] = variation_id
但是,有一个django软件包可以很好地与Google Optimize集成:https://github.com/adinhodovic/django-google-optimize/。
这是有关如何使用该软件包以及Google Optimize如何工作的博客文章:https://hodovi.cc/blog/django-b-testing-google-optimize/。