diff --git a/app/experimenter/experiments/constants.py b/app/experimenter/experiments/constants.py index a4dd978e6..d003b7574 100644 --- a/app/experimenter/experiments/constants.py +++ b/app/experimenter/experiments/constants.py @@ -100,6 +100,14 @@ class ExperimentConstants(object): 'Does this study affect a large number of Release users?') # Help texts + OWNER_HELP_TEXT = """ +
+ The owner of the experiment is the person responsible for ensuring + that it is run in its entirety and is the primary stake holder in + its analysis. +
+ """ + PROJECT_HELP_TEXT = format_lazy("""Choose which project this experiment belongs to. diff --git a/app/experimenter/experiments/forms.py b/app/experimenter/experiments/forms.py index d2274bd08..ade7bb1f9 100644 --- a/app/experimenter/experiments/forms.py +++ b/app/experimenter/experiments/forms.py @@ -1,6 +1,7 @@ import json from django import forms +from django.contrib.auth import get_user_model from django.utils.text import slugify from experimenter.projects.forms import AutoNameSlugFormMixin @@ -36,6 +37,7 @@ class NameSlugMixin(object): class ControlVariantForm(NameSlugMixin, forms.ModelForm): + description = forms.CharField( label='Description', help_text=Experiment.CONTROL_DESCRIPTION_HELP_TEXT, @@ -84,6 +86,7 @@ class ControlVariantForm(NameSlugMixin, forms.ModelForm): class ExperimentalVariantForm(NameSlugMixin, forms.ModelForm): + slug = forms.CharField(required=False) experiment = forms.ModelChoiceField( required=False, queryset=Experiment.objects.all()) @@ -152,6 +155,14 @@ class ChangeLogMixin(object): class ExperimentOverviewForm( AutoNameSlugFormMixin, ChangeLogMixin, forms.ModelForm): + + owner = forms.ModelChoiceField( + required=False, + label='Owner', + help_text=Experiment.OWNER_HELP_TEXT, + queryset=get_user_model().objects.all(), + widget=forms.Select(attrs={'class': 'form-control'}), + ) project = forms.ModelChoiceField( required=False, label='Project', @@ -206,6 +217,7 @@ class ExperimentOverviewForm( class Meta: model = Experiment fields = [ + 'owner', 'project', 'name', 'slug', diff --git a/app/experimenter/experiments/migrations/0009_experiment_owner.py b/app/experimenter/experiments/migrations/0009_experiment_owner.py new file mode 100644 index 000000000..64fbe3f0b --- /dev/null +++ b/app/experimenter/experiments/migrations/0009_experiment_owner.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11 on 2018-05-08 19:15 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('experiments', '0008_auto_20180503_1747'), + ] + + operations = [ + migrations.AddField( + model_name='experiment', + name='owner', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/app/experimenter/experiments/models.py b/app/experimenter/experiments/models.py index aa6b9614d..64702b8fe 100644 --- a/app/experimenter/experiments/models.py +++ b/app/experimenter/experiments/models.py @@ -22,6 +22,7 @@ class ExperimentManager(models.Manager): class Experiment(ExperimentConstants, models.Model): + owner = models.ForeignKey(get_user_model(), blank=True, null=True) project = models.ForeignKey( 'projects.Project', blank=True, diff --git a/app/experimenter/experiments/tests/factories.py b/app/experimenter/experiments/tests/factories.py index 013df2c75..032e8e0f6 100644 --- a/app/experimenter/experiments/tests/factories.py +++ b/app/experimenter/experiments/tests/factories.py @@ -16,6 +16,7 @@ faker = FakerFactory.create() class ExperimentFactory(factory.django.DjangoModelFactory): + owner = factory.SubFactory(UserFactory) project = factory.SubFactory(ProjectFactory) name = factory.LazyAttribute(lambda o: faker.catch_phrase()) slug = factory.LazyAttribute(lambda o: slugify(o.name)) diff --git a/app/experimenter/experiments/tests/test_forms.py b/app/experimenter/experiments/tests/test_forms.py index a5edb0dc9..bb35e71b7 100644 --- a/app/experimenter/experiments/tests/test_forms.py +++ b/app/experimenter/experiments/tests/test_forms.py @@ -198,6 +198,7 @@ class TestExperimentOverviewForm(MockRequestMixin, TestCase): self.project = ProjectFactory.create() self.data = { + 'owner': self.user.id, 'project': self.project.id, 'name': 'A new experiment!', 'short_description': 'Let us learn new things', @@ -215,6 +216,7 @@ class TestExperimentOverviewForm(MockRequestMixin, TestCase): self.assertTrue(form.is_valid()) experiment = form.save() + self.assertEqual(experiment.owner, self.user) self.assertEqual(experiment.project, self.project) self.assertEqual(experiment.status, experiment.STATUS_DRAFT) self.assertEqual(experiment.name, self.data['name']) diff --git a/app/experimenter/experiments/views.py b/app/experimenter/experiments/views.py index 66b5fc4c2..0ae3de7e7 100644 --- a/app/experimenter/experiments/views.py +++ b/app/experimenter/experiments/views.py @@ -110,6 +110,8 @@ class ExperimentCreateView(ExperimentFormMixin, CreateView): if 'project' in self.request.GET: initial['project'] = self.request.GET['project'] + initial['owner'] = self.request.user.id + return initial diff --git a/app/experimenter/templates/base.html b/app/experimenter/templates/base.html index a3eff140d..39187c5f1 100644 --- a/app/experimenter/templates/base.html +++ b/app/experimenter/templates/base.html @@ -62,7 +62,7 @@