Django-AB-project
Here is my first package for Django. I tried to write it so that it would be easy for you to use this package.
It provide four function in utils.py and some models in models.py.
This would be easy to used this package with Generic views in Django, but this can be work properly in methods, just used another technic.
(You can read about Generic Views in Django here - https://docs.djangoproject.com/en/1.11/topics/class-based-views/)
A/B testing (also known as split testing) is a method of comparing two versions of a webpage against each other to determine which is better for users. AB testing is essentially an experiment where two variations of a page are shown to users in random order (In this package all users are divided to two group, and not needed to registrated in your app) and statistical analysis is used to determine which variation performs better for a given conversion goal. What is A/B testing?
1. Use pip to download this package - pip install django-AB-project How to install?
2. Add 'ab', to INSTALLED_APPS in settings.py:
INSTALLED_APPS = [
...
...
'ab',
]
- Configure your sessions - set in settings.py at the end of file (or where you want):
SESSION_EXPIRE_AT_BROWSER_CLOSE = True # Coockie's will be destroyed after browser close
SESSION_COOKIE_AGE = 60 * 60 * 24 # Coockie's will be destroyed after 24 hours
You can edit this lines if you need.
4. Run python manage.py makemigrations, and python manage.py migrate
5. Run server (python manage.py runserver) and go to the admin page. If you see new line named "Ab_Split_Testing" and can click on them without error page - Congratulation! You successfully installed this package.
This package have two main function for each version of views How to use?
(Generic views version)
Let's imagine we have some ListView in views.py
from django.views.generic import ListView
from split_testing.utils import ab_init, success_goal
class IntroPage(ListView):
model = YourModel
template_name = 'pages/intro.html'
First function, called ab_init we need to use when page is loading, to check if user is load this page.
But also, we need some varables (like path to alternative html file, and name for test)
Let's define!
class IntroPage(ListView):
model = YourModel
template_name = 'pages/intro.html'
alternative_template_name = 'alt_pages/intro.html'
page_name = 'intro page'
def dispatch(self, request, *args, **kwargs):
# init for a/b, add +1 to "Entered"
ab_init(self)
# call the view
return super(IntroPage, self).dispatch(request, *args, **kwargs)
Let see what we got:
alternative_template_name = 'alt_pages/intro.html'
Here you need to enter a path to your alternative html file, which you want to test with template_file
Next is:
page_name = 'intro page'
Enter a name for this page(this test will be named like that)
Next scary thing:
def dispatch(self, request, *args, **kwargs):
# init for a/b, add +1 to "Entered"
ab_init(self)
# call the view
return super(IntroPage, self).dispatch(request, *args, **kwargs)
This function will be called when page is loading, so it's perfect place where a/b will be initialized
Let's test our page, go to the urls.py, and write this code:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.IntroPage.as_view(), name='intro_page'),
]
Run your server, and go to 127.0.0.1:8000/
If you don't see any error, and page looks like normal - go to the admin page and check "Ab_Split_Testing"!
Here you see new created object, using your page_name. Click on and you will see some data. Run another browser, or re-enter in your browser and load main page again, and you will see changes.
We successfully initialized our test, but we need collect not only users who entered to our page, but also users, who will make success actions. It would be simple if you need to test forms on your page, but we can test other element's too, just use a little bit of JavaScript.
Testing forms (FormView)
You just need to edit your form_valid method:
from django.shortcuts import redirect
from django.views.generic import FormView
from split_testing.utils import ab_init, success_goal
class SecondPage(FormView):
# A/B testing variables
template_name = 'pages/second_page.html'
alternative_template_name = 'alt_pages/second_page.html'
page_name = 'second page'
form_class = someForm
def dispatch(self, request, *args, **kwargs):
# init for a/b, add +1 to "Entered"
ab_init(self)
# call the view
return super(SecondPage, self).dispatch(request, *args, **kwargs)
def form_valid(self, form):
# Process your forms
...
...
# A/B set successfully goal before redirect
success_goal(self)
return redirect('third_page')
success_goal(self) is second function what this package implement.
Testing using JS (Any other View)
First, you need edit your both html files. Just add to bottom of the body tag this function:
<script type="text/javascript">
function Sendgoal(url_page) {
$.ajax({
url: url_page,
data: {'is_clicked': 'True',
csrfmiddlewaretoken: "{{ csrf_token }}"},
type:"POST",
success: function (data) {
console.log('POST success');
},
});
}
</script>
Then, you need find your button, or link which pressed by user will be send goal to server
<a href='#' onclick="Sendgoal('{% url 'intro_page' %}')">Click me!</a>
We need to edit our IntroPage class, to handle POST request:
class IntroPage(ListView):
model = YourModel
template_name = 'pages/intro.html'
alternative_template_name = 'alt_pages/intro.html'
page_name = 'intro page'
def dispatch(self, request, *args, **kwargs):
# init for a/b, add +1 to "Entered"
ab_init(self)
# call the view
return super(IntroPage, self).dispatch(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
is_clicked = request.POST.get('is_clicked')
if is_clicked == 'True':
# A/B set success goal
success_goal(self)
return JsonResponse({'OK':'OK'})
# if POST request is not equal what we send in template
return JsonResponse({'KO':'KO'})
That's it! Your test is ready, try to test it using another browser.
(Method views version)
Coming soon!