From 832e8e01d2d373dd794561ba64d78f3429253a57 Mon Sep 17 00:00:00 2001 From: andykawabata Date: Wed, 12 Jun 2024 11:30:28 -0400 Subject: [PATCH 1/3] Added setting to allow coders view all labels --- backend/django/core/forms.py | 3 +++ .../0077_project_allow_coders_view_labels.py | 18 ++++++++++++++++++ backend/django/core/models.py | 1 + .../create/create_wizard_advanced.html | 17 +++++++++++++++++ backend/django/core/views/api_annotate.py | 5 ++++- backend/django/core/views/frontend.py | 1 + 6 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 backend/django/core/migrations/0077_project_allow_coders_view_labels.py diff --git a/backend/django/core/forms.py b/backend/django/core/forms.py index 415854b4..ff024584 100644 --- a/backend/django/core/forms.py +++ b/backend/django/core/forms.py @@ -263,6 +263,9 @@ class Meta: required=False, ) + allow_coders_view_labels = forms.BooleanField(initial=False, required=False) + + def clean(self): use_active_learning = self.cleaned_data.get("use_active_learning") use_default_batch_size = self.cleaned_data.get("use_default_batch_size") diff --git a/backend/django/core/migrations/0077_project_allow_coders_view_labels.py b/backend/django/core/migrations/0077_project_allow_coders_view_labels.py new file mode 100644 index 00000000..d4052300 --- /dev/null +++ b/backend/django/core/migrations/0077_project_allow_coders_view_labels.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.9 on 2024-06-12 14:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("core", "0076_auto_20230710_1905"), + ] + + operations = [ + migrations.AddField( + model_name="project", + name="allow_coders_view_labels", + field=models.BooleanField(default=False), + ), + ] diff --git a/backend/django/core/models.py b/backend/django/core/models.py index cf158854..95b01552 100644 --- a/backend/django/core/models.py +++ b/backend/django/core/models.py @@ -44,6 +44,7 @@ class Meta: num_users_irr = models.IntegerField(default=2, validators=[MinValueValidator(2)]) codebook_file = models.TextField(default="") batch_size = models.IntegerField(default=30) + allow_coders_view_labels = models.BooleanField(default=False) umbrella_string = models.TextField(blank=True) """ Advanced options """ # the current options are 'random', 'least confident', 'entropy', and 'margin sampling' diff --git a/backend/django/core/templates/projects/create/create_wizard_advanced.html b/backend/django/core/templates/projects/create/create_wizard_advanced.html index 6139d6d7..4a1c43a7 100644 --- a/backend/django/core/templates/projects/create/create_wizard_advanced.html +++ b/backend/django/core/templates/projects/create/create_wizard_advanced.html @@ -118,6 +118,23 @@
+ + +
+ +
+
+
+ Allow coders to view other users' labels in history table: {{ wizard.form.allow_coders_view_labels }} +
+
+
diff --git a/backend/django/core/views/api_annotate.py b/backend/django/core/views/api_annotate.py index abec22a9..897075af 100644 --- a/backend/django/core/views/api_annotate.py +++ b/backend/django/core/views/api_annotate.py @@ -996,7 +996,10 @@ def get_label_history(request, project_pk): finalized_irr_data = IRRLog.objects.filter(data__irr_ind=False).values_list( "data__pk", flat=True ) - if project_extras.proj_permission_level(project, profile) >= 2: + if ( + project_extras.proj_permission_level(project, profile) >= 2 + or project.allow_coders_view_labels + ): labeled_data = DataLabel.objects.filter( data__project=project_pk, label__in=labels ).exclude(data__in=finalized_irr_data) diff --git a/backend/django/core/views/frontend.py b/backend/django/core/views/frontend.py index 23f5fd8b..9422bce0 100644 --- a/backend/django/core/views/frontend.py +++ b/backend/django/core/views/frontend.py @@ -325,6 +325,7 @@ def done(self, form_list, form_dict, **kwargs): proj_obj.percentage_irr = advanced_data["percentage_irr"] proj_obj.num_users_irr = advanced_data["num_users_irr"] proj_obj.classifier = advanced_data["classifier"] + proj_obj.allow_coders_view_labels = advanced_data["allow_coders_view_labels"] # use the data dedup choice to set dedup property of metadata fields proj_obj.dedup_on = data.cleaned_data["dedup_on"] From 8d8e8ed1ce3a7ecaef6755969535311b035de5fd Mon Sep 17 00:00:00 2001 From: andykawabata Date: Fri, 14 Jun 2024 09:28:58 -0400 Subject: [PATCH 2/3] Added advanced settings update form --- backend/django/core/forms.py | 6 +++ .../create/create_wizard_advanced.html | 4 +- .../templates/projects/update/advanced.html | 40 +++++++++++++++++++ .../templates/projects/update_landing.html | 1 + backend/django/core/urls/projects.py | 5 +++ backend/django/core/views/frontend.py | 28 +++++++++++++ 6 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 backend/django/core/templates/projects/update/advanced.html diff --git a/backend/django/core/forms.py b/backend/django/core/forms.py index ff024584..51d4de0c 100644 --- a/backend/django/core/forms.py +++ b/backend/django/core/forms.py @@ -136,6 +136,12 @@ class Meta: description = forms.CharField(required=False) +class ProjectUpdateAdvancedForm(forms.ModelForm): + class Meta: + model = Project + fields = ["allow_coders_view_labels"] + + class LabelForm(forms.ModelForm): class Meta: model = Label diff --git a/backend/django/core/templates/projects/create/create_wizard_advanced.html b/backend/django/core/templates/projects/create/create_wizard_advanced.html index 4a1c43a7..4319847c 100644 --- a/backend/django/core/templates/projects/create/create_wizard_advanced.html +++ b/backend/django/core/templates/projects/create/create_wizard_advanced.html @@ -34,7 +34,7 @@
-

Train and display results for a model: {{ wizard.form.use_model }}

+

{{ wizard.form.use_model }} Train and display results for a model

NOTE: This option must be checked to use Active Learning


@@ -131,7 +131,7 @@
- Allow coders to view other users' labels in history table: {{ wizard.form.allow_coders_view_labels }} + {{ wizard.form.allow_coders_view_labels }} Allow coders to view other users' labels in history table
diff --git a/backend/django/core/templates/projects/update/advanced.html b/backend/django/core/templates/projects/update/advanced.html new file mode 100644 index 00000000..a1a63cf6 --- /dev/null +++ b/backend/django/core/templates/projects/update/advanced.html @@ -0,0 +1,40 @@ +{% extends "base.html" %} +{% block page_title %}Update Project Overview{% endblock %} +{% load static %} +{% load render_bundle from webpack_loader %} + +{% block content %} +
+
+
+
+ {{ form.media.css }} +
+ {% csrf_token %} +
+
+ +
+
+
+ {{ form.allow_coders_view_labels }} Allow coders to view other users' labels in history table +
+
+
+
+
+ + + +
+
+
+
+
+{% endblock %} diff --git a/backend/django/core/templates/projects/update_landing.html b/backend/django/core/templates/projects/update_landing.html index 6ac47327..727b2732 100644 --- a/backend/django/core/templates/projects/update_landing.html +++ b/backend/django/core/templates/projects/update_landing.html @@ -13,6 +13,7 @@

Update Project

  • {% if project.codebook_file == '' %}Upload Codebook{% else %}Change Codebook{% endif%}
  • Update Project Permissions
  • Update Label Descriptions
  • +
  • Update Advanced Settings
  • Add Project To Group
  • diff --git a/backend/django/core/urls/projects.py b/backend/django/core/urls/projects.py index 34200f92..0f3b895a 100644 --- a/backend/django/core/urls/projects.py +++ b/backend/django/core/urls/projects.py @@ -31,6 +31,11 @@ frontend.ProjectUpdateOverview.as_view(), name="project_update_overview", ), + re_path( + r"^projects/(?P\d+)/update/advanced/$", + frontend.ProjectUpdateAdvanced.as_view(), + name="project_update_advanced", + ), re_path( r"^projects/(?P\d+)/update/data/$", frontend.ProjectUpdateData.as_view(), diff --git a/backend/django/core/views/frontend.py b/backend/django/core/views/frontend.py index 9422bce0..7c6acc27 100644 --- a/backend/django/core/views/frontend.py +++ b/backend/django/core/views/frontend.py @@ -21,6 +21,7 @@ LabelFormSet, PermissionsFormSet, ProjectUpdateOverviewForm, + ProjectUpdateAdvancedForm, ProjectWizardForm, ) from core.models import ( @@ -444,6 +445,33 @@ def form_valid(self, form): else: return self.render_to_response(context) +class ProjectUpdateAdvanced(LoginRequiredMixin, UserPassesTestMixin, UpdateView): + model = Project + form_class = ProjectUpdateAdvancedForm + template_name = "projects/update/advanced.html" + permission_denied_message = ( + "You must be an Admin or Project Creator to access the Advanced Project Settings Update page." + ) + raise_exception = True + + def test_func(self): + project = Project.objects.get(pk=self.kwargs["pk"]) + + return ( + project_extras.proj_permission_level(project, self.request.user.profile) + >= 2 + ) + + def form_valid(self, form): + context = self.get_context_data() + if form.is_valid(): + with transaction.atomic(): + self.object = form.save() + return redirect(self.get_success_url()) + else: + return self.render_to_response(context) + + class ProjectUpdateData(LoginRequiredMixin, UserPassesTestMixin, UpdateView): model = Project From c1802fa023a78b3c6f698e21d6506b57d04c05e4 Mon Sep 17 00:00:00 2001 From: andykawabata Date: Tue, 18 Jun 2024 16:26:48 -0400 Subject: [PATCH 3/3] Disable option when IRR used --- backend/django/core/forms.py | 7 ++- .../create/create_wizard_advanced.html | 47 ++++++++++++++++--- .../templates/projects/update/advanced.html | 3 ++ backend/django/core/views/frontend.py | 7 +++ 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/backend/django/core/forms.py b/backend/django/core/forms.py index 51d4de0c..b87148c3 100644 --- a/backend/django/core/forms.py +++ b/backend/django/core/forms.py @@ -140,7 +140,12 @@ class ProjectUpdateAdvancedForm(forms.ModelForm): class Meta: model = Project fields = ["allow_coders_view_labels"] - + + def __init__(self, *args, **kwargs): + percentage_irr = kwargs.pop('percentage_irr') + super(ProjectUpdateAdvancedForm, self).__init__(*args, **kwargs) + if percentage_irr > 0: + self.fields['allow_coders_view_labels'].widget.attrs['disabled'] = 'disabled' class LabelForm(forms.ModelForm): class Meta: diff --git a/backend/django/core/templates/projects/create/create_wizard_advanced.html b/backend/django/core/templates/projects/create/create_wizard_advanced.html index 4319847c..65d3547a 100644 --- a/backend/django/core/templates/projects/create/create_wizard_advanced.html +++ b/backend/django/core/templates/projects/create/create_wizard_advanced.html @@ -85,16 +85,24 @@
    +

    Under IRR, a certain percentage of the data is labeled by + multiple coders. The project admin can then examine the + consistency of the labels across different coders. The options + below allow you to set what percentage of the data is coded + multiple times, and how many coders must code data designated + for IRR before it is analyzed. +

    -

    Under IRR, a certain percentage of the data is labeled by - multiple coders. The project admin can then examine the - consistency of the labels across different coders. The options - below allow you to set what percentage of the data is coded - multiple times, and how many coders must code data designated - for IRR before it is analyzed. -

    {{ wizard.form.use_irr }} Use Inter-rater Reliability
    +
    Percent of batch marked IRR (must be between 0 and 100):{{ wizard.form.percentage_irr }}%
    @@ -133,6 +141,13 @@
    {{ wizard.form.allow_coders_view_labels }} Allow coders to view other users' labels in history table
    + +
    @@ -162,10 +177,14 @@
    */ var methods_box = $('div#choose_method_box'); var irr_box = $('div#IRR_options'); +var irr_or_not_box = $('div#choose_irr_or_not'); +var irr_or_not_box_disabled = $('div#choose_irr_or_not_disabled'); var batch_field = $('#choose_batch_size'); var use_model = $('#use_model_div'); var class_choice = $('#classifier_radios'); var al_tab = $('#al_tab'); +var allow_coders_box = $('#allow_coders_view_labels'); +var allow_coders_box_disabled = $('#allow_coders_view_labels_disabled'); if ($('input#id_advanced-use_irr').prop('checked') == true) { irr_box.show(); @@ -225,8 +244,22 @@
    $('input#id_advanced-use_irr').change(function() { if ($(this).prop('checked') == true) { irr_box.show(); + allow_coders_box.hide(); + allow_coders_box_disabled.show(); } else { irr_box.hide(); + allow_coders_box.show() + allow_coders_box_disabled.hide(); + } +}); + +$('input#id_advanced-allow_coders_view_labels').change(function() { + if ($(this).prop('checked') == true) { + irr_or_not_box.hide(); + irr_or_not_box_disabled.show(); + } else { + irr_or_not_box.show(); + irr_or_not_box_disabled.hide(); } }); diff --git a/backend/django/core/templates/projects/update/advanced.html b/backend/django/core/templates/projects/update/advanced.html index a1a63cf6..99affa88 100644 --- a/backend/django/core/templates/projects/update/advanced.html +++ b/backend/django/core/templates/projects/update/advanced.html @@ -25,6 +25,9 @@
    {{ form.allow_coders_view_labels }} Allow coders to view other users' labels in history table
    + + *This option is only enabled if project does not use IRR + diff --git a/backend/django/core/views/frontend.py b/backend/django/core/views/frontend.py index 7c6acc27..abf97437 100644 --- a/backend/django/core/views/frontend.py +++ b/backend/django/core/views/frontend.py @@ -462,6 +462,13 @@ def test_func(self): >= 2 ) + def get_form_kwargs(self): + # pass the percentage_irr to the form + kwargs = super().get_form_kwargs() + project = self.get_object() + kwargs['percentage_irr'] = project.percentage_irr + return kwargs + def form_valid(self, form): context = self.get_context_data() if form.is_valid():