djangocms-ab-testing 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- djangocms_ab_testing-0.1.0/LICENSE +21 -0
- djangocms_ab_testing-0.1.0/PKG-INFO +205 -0
- djangocms_ab_testing-0.1.0/README.md +174 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/__init__.py +0 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/ab_utils.py +42 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/admin.py +287 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/apps.py +7 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/cms_plugins.py +64 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/conf.py +7 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/management/__init__.py +0 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/management/commands/__init__.py +0 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/management/commands/seed_ab_data.py +77 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/middleware.py +25 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/migrations/0001_initial.py +88 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/migrations/__init__.py +0 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/models.py +110 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/urls.py +7 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing/views.py +51 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing.egg-info/PKG-INFO +205 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing.egg-info/SOURCES.txt +23 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing.egg-info/dependency_links.txt +1 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing.egg-info/requires.txt +4 -0
- djangocms_ab_testing-0.1.0/djangocms_ab_testing.egg-info/top_level.txt +1 -0
- djangocms_ab_testing-0.1.0/pyproject.toml +52 -0
- djangocms_ab_testing-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sergei Gordeichuk
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: djangocms-ab-testing
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A/B testing plugin for django CMS with round-robin assignment, cookie-based persistence, event tracking, and an admin dashboard.
|
|
5
|
+
Author: Sergei Gordeichuk
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/sgordeychuk/djangocms-ab-testing
|
|
8
|
+
Project-URL: Documentation, https://github.com/sgordeychuk/djangocms-ab-testing#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/sgordeychuk/djangocms-ab-testing
|
|
10
|
+
Project-URL: Issues, https://github.com/sgordeychuk/djangocms-ab-testing/issues
|
|
11
|
+
Keywords: django-cms,ab-testing,split-testing,conversion-optimization,cms-plugin,django,a-b-testing,multivariate-testing
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Framework :: Django
|
|
14
|
+
Classifier: Framework :: Django :: 4.2
|
|
15
|
+
Classifier: Framework :: Django CMS
|
|
16
|
+
Classifier: Framework :: Django CMS :: 3.11
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: django>=3.2
|
|
27
|
+
Requires-Dist: django-cms>=3.11
|
|
28
|
+
Requires-Dist: django-import-export>=3.0
|
|
29
|
+
Requires-Dist: user-agents>=2.0
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
# djangocms-ab-testing
|
|
33
|
+
|
|
34
|
+
[](https://pypi.org/project/djangocms-ab-testing/)
|
|
35
|
+
[](https://pypi.org/project/djangocms-ab-testing/)
|
|
36
|
+
[](https://pypi.org/project/djangocms-ab-testing/)
|
|
37
|
+
[](https://opensource.org/licenses/MIT)
|
|
38
|
+
|
|
39
|
+
A full-featured **A/B testing** (split testing) plugin for **django CMS**. Run conversion optimization experiments directly in the CMS page editor with round-robin variant assignment, cookie-based persistence, client-side event tracking, and a built-in admin dashboard with Chart.js visualizations.
|
|
40
|
+
|
|
41
|
+
## Features
|
|
42
|
+
|
|
43
|
+
- **CMS plugin-based setup** - Add A/B test containers and variants directly in the django CMS page editor
|
|
44
|
+
- **Round-robin assignment** - Fair variant distribution using an atomic database counter
|
|
45
|
+
- **Cookie persistence** - Visitors see the same variant for 30 days (`ab_variant_<slug>`)
|
|
46
|
+
- **Event tracking API** - POST events to `/api/ab-event/` with CSRF protection
|
|
47
|
+
- **Auto "view" tracking** - Fires automatically when a variant is rendered
|
|
48
|
+
- **Bootstrap modal tracking** - Tracks `shown.bs.modal`, `hidden.bs.modal`, and CTA button clicks
|
|
49
|
+
- **Configurable actions** - Define custom tracking events via `AB_TESTING_VALID_ACTIONS` setting
|
|
50
|
+
- **Admin dashboard** - Chart.js-powered visualizations with summary cards, per-variant stats, daily trends, and conversion rate charts
|
|
51
|
+
- **Distribution breakdowns** - Analyze results by device type, browser, OS, and screen size
|
|
52
|
+
- **Filtering** - Filter dashboard data by date range and device properties
|
|
53
|
+
- **CSV export** - Export event data via django-import-export
|
|
54
|
+
- **Cache control** - Pages with A/B tests automatically get `Cache-Control: private, no-store`
|
|
55
|
+
|
|
56
|
+
## Screenshots
|
|
57
|
+
|
|
58
|
+
### Light theme
|
|
59
|
+

|
|
60
|
+
|
|
61
|
+
### Dark theme
|
|
62
|
+

|
|
63
|
+
|
|
64
|
+
## Installation
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
pip install djangocms-ab-testing
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Add to `INSTALLED_APPS`:
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
INSTALLED_APPS = [
|
|
74
|
+
# ...
|
|
75
|
+
"djangocms_ab_testing",
|
|
76
|
+
]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Add the middleware (after `SessionMiddleware`):
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
MIDDLEWARE = [
|
|
83
|
+
# ...
|
|
84
|
+
"django.contrib.sessions.middleware.SessionMiddleware",
|
|
85
|
+
"djangocms_ab_testing.middleware.ABCookieMiddleware",
|
|
86
|
+
# ...
|
|
87
|
+
]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Add the URL config:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from django.urls import include, path
|
|
94
|
+
|
|
95
|
+
urlpatterns = [
|
|
96
|
+
# ...
|
|
97
|
+
path("api/", include("djangocms_ab_testing.urls")),
|
|
98
|
+
]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Run migrations:
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
python manage.py migrate djangocms_ab_testing
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Usage
|
|
108
|
+
|
|
109
|
+
### 1. Create an AB Test
|
|
110
|
+
|
|
111
|
+
Go to **Django Admin > AB Tests** and create a test with a name and slug.
|
|
112
|
+
|
|
113
|
+
### 2. Add CMS Plugins
|
|
114
|
+
|
|
115
|
+
In the django CMS page editor:
|
|
116
|
+
|
|
117
|
+
1. Add an **A/B Test Container** plugin and link it to your test
|
|
118
|
+
2. Inside the container, add **A/B Test Variant** plugins (e.g. variant key `A`, `B`)
|
|
119
|
+
3. Add your content inside each variant
|
|
120
|
+
|
|
121
|
+
### 3. Track Events
|
|
122
|
+
|
|
123
|
+
Include the tracking script in your template:
|
|
124
|
+
|
|
125
|
+
```html
|
|
126
|
+
<script src="{% static 'djangocms_ab_testing/js/ab_tracking.js' %}"></script>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The script auto-initializes, fires a `view` event when the variant is rendered, and tracks Bootstrap modal events (`shown.bs.modal`, `hidden.bs.modal`). Add the `ab-request-btn` class to CTA buttons inside modals to track conversion clicks.
|
|
130
|
+
|
|
131
|
+
For custom tracking, call `window.initABTracking()` after dynamic content loads.
|
|
132
|
+
|
|
133
|
+
### 4. View Results
|
|
134
|
+
|
|
135
|
+
Open any AB Test in the admin to see the dashboard with:
|
|
136
|
+
|
|
137
|
+
- Summary cards (total events, unique sessions, counter)
|
|
138
|
+
- Per-variant stats table (views, opens, requests, closes, conversion rate)
|
|
139
|
+
- Daily trends and conversion rate charts
|
|
140
|
+
- Distribution breakdowns by device, browser, OS, screen size
|
|
141
|
+
- Filterable by date range and device properties
|
|
142
|
+
- CSV export via django-import-export
|
|
143
|
+
|
|
144
|
+
## Configuration
|
|
145
|
+
|
|
146
|
+
### Custom Tracking Actions
|
|
147
|
+
|
|
148
|
+
By default, the following actions are tracked: `view`, `opened`, `closed`, `requested`.
|
|
149
|
+
|
|
150
|
+
To define custom actions, add `AB_TESTING_VALID_ACTIONS` to your Django settings:
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
AB_TESTING_VALID_ACTIONS = {"view", "opened", "closed", "requested", "submitted", "purchased"}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The event tracking API will only accept actions in this set. The admin dashboard and seed command will also use these actions automatically.
|
|
157
|
+
|
|
158
|
+
## How It Works
|
|
159
|
+
|
|
160
|
+
- **Variant assignment**: Round-robin via atomic database counter
|
|
161
|
+
- **Persistence**: 30-day cookie per test (`ab_variant_<slug>`)
|
|
162
|
+
- **Cache**: Pages with A/B tests get `Cache-Control: private, no-store`
|
|
163
|
+
- **Events**: Tracked via POST to `/api/ab-event/` with CSRF protection
|
|
164
|
+
|
|
165
|
+
## Management Commands
|
|
166
|
+
|
|
167
|
+
```sh
|
|
168
|
+
python manage.py seed_ab_data --events 500 --days 30
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Generates dummy event data for dashboard testing.
|
|
172
|
+
|
|
173
|
+
## Publishing to PyPI
|
|
174
|
+
|
|
175
|
+
1. Install build tools:
|
|
176
|
+
|
|
177
|
+
```sh
|
|
178
|
+
pip install build twine
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
2. Build the package:
|
|
182
|
+
|
|
183
|
+
```sh
|
|
184
|
+
python -m build
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
3. Upload to TestPyPI first:
|
|
188
|
+
|
|
189
|
+
```sh
|
|
190
|
+
twine upload --repository testpypi dist/*
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
4. Upload to PyPI:
|
|
194
|
+
|
|
195
|
+
```sh
|
|
196
|
+
twine upload dist/*
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Contributing
|
|
200
|
+
|
|
201
|
+
Contributions are welcome! Please open an issue or submit a pull request on [GitHub](https://github.com/sgordeychuk/djangocms-ab-testing).
|
|
202
|
+
|
|
203
|
+
## License
|
|
204
|
+
|
|
205
|
+
MIT
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# djangocms-ab-testing
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/djangocms-ab-testing/)
|
|
4
|
+
[](https://pypi.org/project/djangocms-ab-testing/)
|
|
5
|
+
[](https://pypi.org/project/djangocms-ab-testing/)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
A full-featured **A/B testing** (split testing) plugin for **django CMS**. Run conversion optimization experiments directly in the CMS page editor with round-robin variant assignment, cookie-based persistence, client-side event tracking, and a built-in admin dashboard with Chart.js visualizations.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **CMS plugin-based setup** - Add A/B test containers and variants directly in the django CMS page editor
|
|
13
|
+
- **Round-robin assignment** - Fair variant distribution using an atomic database counter
|
|
14
|
+
- **Cookie persistence** - Visitors see the same variant for 30 days (`ab_variant_<slug>`)
|
|
15
|
+
- **Event tracking API** - POST events to `/api/ab-event/` with CSRF protection
|
|
16
|
+
- **Auto "view" tracking** - Fires automatically when a variant is rendered
|
|
17
|
+
- **Bootstrap modal tracking** - Tracks `shown.bs.modal`, `hidden.bs.modal`, and CTA button clicks
|
|
18
|
+
- **Configurable actions** - Define custom tracking events via `AB_TESTING_VALID_ACTIONS` setting
|
|
19
|
+
- **Admin dashboard** - Chart.js-powered visualizations with summary cards, per-variant stats, daily trends, and conversion rate charts
|
|
20
|
+
- **Distribution breakdowns** - Analyze results by device type, browser, OS, and screen size
|
|
21
|
+
- **Filtering** - Filter dashboard data by date range and device properties
|
|
22
|
+
- **CSV export** - Export event data via django-import-export
|
|
23
|
+
- **Cache control** - Pages with A/B tests automatically get `Cache-Control: private, no-store`
|
|
24
|
+
|
|
25
|
+
## Screenshots
|
|
26
|
+
|
|
27
|
+
### Light theme
|
|
28
|
+

|
|
29
|
+
|
|
30
|
+
### Dark theme
|
|
31
|
+

|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
pip install djangocms-ab-testing
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Add to `INSTALLED_APPS`:
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
INSTALLED_APPS = [
|
|
43
|
+
# ...
|
|
44
|
+
"djangocms_ab_testing",
|
|
45
|
+
]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Add the middleware (after `SessionMiddleware`):
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
MIDDLEWARE = [
|
|
52
|
+
# ...
|
|
53
|
+
"django.contrib.sessions.middleware.SessionMiddleware",
|
|
54
|
+
"djangocms_ab_testing.middleware.ABCookieMiddleware",
|
|
55
|
+
# ...
|
|
56
|
+
]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Add the URL config:
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from django.urls import include, path
|
|
63
|
+
|
|
64
|
+
urlpatterns = [
|
|
65
|
+
# ...
|
|
66
|
+
path("api/", include("djangocms_ab_testing.urls")),
|
|
67
|
+
]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Run migrations:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
python manage.py migrate djangocms_ab_testing
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Usage
|
|
77
|
+
|
|
78
|
+
### 1. Create an AB Test
|
|
79
|
+
|
|
80
|
+
Go to **Django Admin > AB Tests** and create a test with a name and slug.
|
|
81
|
+
|
|
82
|
+
### 2. Add CMS Plugins
|
|
83
|
+
|
|
84
|
+
In the django CMS page editor:
|
|
85
|
+
|
|
86
|
+
1. Add an **A/B Test Container** plugin and link it to your test
|
|
87
|
+
2. Inside the container, add **A/B Test Variant** plugins (e.g. variant key `A`, `B`)
|
|
88
|
+
3. Add your content inside each variant
|
|
89
|
+
|
|
90
|
+
### 3. Track Events
|
|
91
|
+
|
|
92
|
+
Include the tracking script in your template:
|
|
93
|
+
|
|
94
|
+
```html
|
|
95
|
+
<script src="{% static 'djangocms_ab_testing/js/ab_tracking.js' %}"></script>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The script auto-initializes, fires a `view` event when the variant is rendered, and tracks Bootstrap modal events (`shown.bs.modal`, `hidden.bs.modal`). Add the `ab-request-btn` class to CTA buttons inside modals to track conversion clicks.
|
|
99
|
+
|
|
100
|
+
For custom tracking, call `window.initABTracking()` after dynamic content loads.
|
|
101
|
+
|
|
102
|
+
### 4. View Results
|
|
103
|
+
|
|
104
|
+
Open any AB Test in the admin to see the dashboard with:
|
|
105
|
+
|
|
106
|
+
- Summary cards (total events, unique sessions, counter)
|
|
107
|
+
- Per-variant stats table (views, opens, requests, closes, conversion rate)
|
|
108
|
+
- Daily trends and conversion rate charts
|
|
109
|
+
- Distribution breakdowns by device, browser, OS, screen size
|
|
110
|
+
- Filterable by date range and device properties
|
|
111
|
+
- CSV export via django-import-export
|
|
112
|
+
|
|
113
|
+
## Configuration
|
|
114
|
+
|
|
115
|
+
### Custom Tracking Actions
|
|
116
|
+
|
|
117
|
+
By default, the following actions are tracked: `view`, `opened`, `closed`, `requested`.
|
|
118
|
+
|
|
119
|
+
To define custom actions, add `AB_TESTING_VALID_ACTIONS` to your Django settings:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
AB_TESTING_VALID_ACTIONS = {"view", "opened", "closed", "requested", "submitted", "purchased"}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The event tracking API will only accept actions in this set. The admin dashboard and seed command will also use these actions automatically.
|
|
126
|
+
|
|
127
|
+
## How It Works
|
|
128
|
+
|
|
129
|
+
- **Variant assignment**: Round-robin via atomic database counter
|
|
130
|
+
- **Persistence**: 30-day cookie per test (`ab_variant_<slug>`)
|
|
131
|
+
- **Cache**: Pages with A/B tests get `Cache-Control: private, no-store`
|
|
132
|
+
- **Events**: Tracked via POST to `/api/ab-event/` with CSRF protection
|
|
133
|
+
|
|
134
|
+
## Management Commands
|
|
135
|
+
|
|
136
|
+
```sh
|
|
137
|
+
python manage.py seed_ab_data --events 500 --days 30
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Generates dummy event data for dashboard testing.
|
|
141
|
+
|
|
142
|
+
## Publishing to PyPI
|
|
143
|
+
|
|
144
|
+
1. Install build tools:
|
|
145
|
+
|
|
146
|
+
```sh
|
|
147
|
+
pip install build twine
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
2. Build the package:
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
python -m build
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
3. Upload to TestPyPI first:
|
|
157
|
+
|
|
158
|
+
```sh
|
|
159
|
+
twine upload --repository testpypi dist/*
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
4. Upload to PyPI:
|
|
163
|
+
|
|
164
|
+
```sh
|
|
165
|
+
twine upload dist/*
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Contributing
|
|
169
|
+
|
|
170
|
+
Contributions are welcome! Please open an issue or submit a pull request on [GitHub](https://github.com/sgordeychuk/djangocms-ab-testing).
|
|
171
|
+
|
|
172
|
+
## License
|
|
173
|
+
|
|
174
|
+
MIT
|
|
File without changes
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from user_agents import parse as ua_parse
|
|
2
|
+
|
|
3
|
+
from djangocms_ab_testing.models import ABCounter
|
|
4
|
+
|
|
5
|
+
COOKIE_NAME_PREFIX = "ab_variant_"
|
|
6
|
+
COOKIE_MAX_AGE = 60 * 60 * 24 * 30 # 30 days
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_ab_variant(request, test_name, variant_keys):
|
|
10
|
+
"""
|
|
11
|
+
Get the variant for this request. Checks cookie first, then round-robin.
|
|
12
|
+
Queues the cookie to be set in the response via middleware.
|
|
13
|
+
"""
|
|
14
|
+
cookie_name = COOKIE_NAME_PREFIX + test_name
|
|
15
|
+
variant_key = request.COOKIES.get(cookie_name)
|
|
16
|
+
|
|
17
|
+
if variant_key and variant_key in variant_keys:
|
|
18
|
+
return variant_key
|
|
19
|
+
|
|
20
|
+
# Assign via round-robin
|
|
21
|
+
variant_key = ABCounter.next_variant(test_name, list(variant_keys))
|
|
22
|
+
|
|
23
|
+
# Queue cookie to be set by middleware
|
|
24
|
+
if not hasattr(request, '_ab_cookies_to_set'):
|
|
25
|
+
request._ab_cookies_to_set = {}
|
|
26
|
+
request._ab_cookies_to_set[cookie_name] = variant_key
|
|
27
|
+
|
|
28
|
+
return variant_key
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def get_device_info(request):
|
|
32
|
+
"""Parse device info from User-Agent header."""
|
|
33
|
+
ua_string = request.META.get('HTTP_USER_AGENT', '')
|
|
34
|
+
ua = ua_parse(ua_string)
|
|
35
|
+
return {
|
|
36
|
+
'device_type': 'mobile' if ua.is_mobile else ('tablet' if ua.is_tablet else 'desktop'),
|
|
37
|
+
'browser': str(ua.browser.family),
|
|
38
|
+
'browser_version': str(ua.browser.version_string),
|
|
39
|
+
'os': str(ua.os.family),
|
|
40
|
+
'os_version': str(ua.os.version_string),
|
|
41
|
+
'is_bot': ua.is_bot,
|
|
42
|
+
}
|