Skip to content

Commit

Permalink
Merge pull request #266 from UW-GAC/deploy/stage
Browse files Browse the repository at this point in the history
Deploy to prod
  • Loading branch information
amstilp authored Jun 20, 2023
2 parents 6b3170e + 1156c73 commit e18d46a
Show file tree
Hide file tree
Showing 26 changed files with 1,685 additions and 315 deletions.
11 changes: 9 additions & 2 deletions gregor_django/gregor_anvil/adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ class AccountAdapter(BaseAccountAdapter):

def get_autocomplete_queryset(self, queryset, q):
"""Filter to Accounts where the email or the associated user name matches the query `q`."""
queryset = queryset.filter(Q(email__icontains=q) | Q(user__name__icontains=q))
if q:
queryset = queryset.filter(
Q(email__icontains=q) | Q(user__name__icontains=q)
)
return queryset

def get_autocomplete_label(self, account):
Expand Down Expand Up @@ -41,6 +44,10 @@ def get_autocomplete_queryset(self, queryset, q, forwarded={}):
if consent_group:
queryset = queryset.filter(consent_group=consent_group)

upload_cycle = forwarded.get("upload_cycle", None)
if upload_cycle:
queryset = queryset.filter(upload_cycle=upload_cycle)

if q:
queryset = queryset.filter(workspace__name__icontains=q)

Expand Down Expand Up @@ -79,7 +86,7 @@ class CombinedConsortiumDataWorkspaceAdapter(BaseWorkspaceAdapter):
type = "combined_consortium"
name = "Combined consortium data workspace"
description = "Workspaces for internal consortium use that contain data tables combined across upload workspaces"
list_table_class = tables.DefaultWorkspaceTable
list_table_class = tables.CombinedConsortiumDataWorkspaceTable
workspace_data_model = models.CombinedConsortiumDataWorkspace
workspace_data_form_class = forms.CombinedConsortiumDataWorkspaceForm
workspace_detail_template_name = (
Expand Down
20 changes: 18 additions & 2 deletions gregor_django/gregor_anvil/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class UploadWorkspaceAdmin(SimpleHistoryAdmin):
"workspace",
"research_center",
"consent_group",
"version",
"upload_cycle",
)
list_filter = (
"research_center",
Expand All @@ -77,5 +77,21 @@ class UploadWorkspaceAdmin(SimpleHistoryAdmin):
sortable_by = (
"id",
"workspace",
"version",
"upload_cycle",
)


@admin.register(models.UploadCycle)
class UploadCycleAdmin(SimpleHistoryAdmin):
"""Admin class for the UploadCycle model."""

list_display = (
"cycle",
"start_date",
"end_date",
)
sortable_by = (
"cycle",
"start_date",
"end_date",
)
91 changes: 71 additions & 20 deletions gregor_django/gregor_anvil/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,28 @@
from . import models


class CustomDateInput(forms.widgets.DateInput):
input_type = "date"


class UploadCycleForm(forms.ModelForm):
"""Form for a UploadCycle object."""

class Meta:
model = models.UploadCycle
fields = (
"cycle",
"start_date",
"end_date",
"note",
)

widgets = {
"start_date": CustomDateInput(),
"end_date": CustomDateInput(),
}


class UploadWorkspaceForm(forms.ModelForm):
"""Form for a UploadWorkspace object."""

Expand All @@ -17,7 +39,7 @@ class Meta:
fields = (
"research_center",
"consent_group",
"version",
"upload_cycle",
"workspace",
)

Expand All @@ -41,11 +63,13 @@ class Meta:
class CombinedConsortiumDataWorkspaceForm(Bootstrap5MediaFormMixin, forms.ModelForm):
"""Form for a CombinedConsortiumDataWorkspace object."""

ERROR_UPLOAD_VERSION_DOES_NOT_MATCH = "Version of upload workspaces does not match."
ERROR_UPLOAD_CYCLE_DOES_NOT_MATCH = (
"upload_cycle must match upload_cycle for upload_workspaces."
)

class Meta:
model = models.CombinedConsortiumDataWorkspace
fields = ("workspace", "upload_workspaces")
fields = ("workspace", "upload_cycle", "upload_workspaces")
help_texts = {
"upload_workspaces": """Upload workspaces contributing to the combined workspace.
All upload workspaces must have the same version."""
Expand All @@ -57,23 +81,33 @@ class Meta:
args=["upload"],
),
attrs={"data-theme": "bootstrap-5"},
forward=["upload_cycle"],
),
}

def clean_upload_workspaces(self):
"""Validate that all UploadWorkspaces have the same version."""
data = self.cleaned_data["upload_workspaces"]
versions = set([x.version for x in data])
if len(versions) > 1:
self.add_error(
"upload_workspaces",
ValidationError(self.ERROR_UPLOAD_VERSION_DOES_NOT_MATCH),
def clean(self):
cleaned_data = super().clean()
if "upload_cycle" in cleaned_data and "upload_workspaces" in cleaned_data:
upload_cycle = cleaned_data["upload_cycle"]
upload_workspace_cycles = set(
[x.upload_cycle for x in cleaned_data["upload_workspaces"]]
)
return data


class CustomDateInput(forms.widgets.DateInput):
input_type = "date"
if len(upload_workspace_cycles) > 1:
raise ValidationError(self.ERROR_UPLOAD_CYCLE_DOES_NOT_MATCH)
x = upload_workspace_cycles.pop()
if x != upload_cycle:
raise ValidationError(self.ERROR_UPLOAD_CYCLE_DOES_NOT_MATCH)

# def clean_upload_workspaces(self):
# """Validate that all UploadWorkspaces have the same version."""
# data = self.cleaned_data["upload_workspaces"]
# versions = set([x.version for x in data])
# if len(versions) > 1:
# self.add_error(
# "upload_workspaces",
# ValidationError(self.ERROR_UPLOAD_VERSION_DOES_NOT_MATCH),
# )
# return data


class ReleaseWorkspaceForm(Bootstrap5MediaFormMixin, forms.ModelForm):
Expand All @@ -85,10 +119,14 @@ class ReleaseWorkspaceForm(Bootstrap5MediaFormMixin, forms.ModelForm):
ERROR_UPLOAD_WORKSPACE_CONSENT = (
"Consent group for upload workspaces must be the same."
)
ERROR_UPLOAD_CYCLE = (
"upload_cycle must match upload_cycle of all upload_workspaces."
)

class Meta:
model = models.ReleaseWorkspace
fields = (
"upload_cycle",
"consent_group",
"upload_workspaces",
"full_data_use_limitations",
Expand All @@ -108,9 +146,12 @@ class Meta:
# Unfortunately we need to select only those with a given consent, not all workspaces.
# So go back to the ModelSelect2Multiple widget.
"upload_workspaces": autocomplete.ModelSelect2Multiple(
url="gregor_anvil:upload_workspaces:autocomplete",
url=reverse(
"anvil_consortium_manager:workspaces:autocomplete_by_type",
args=["upload"],
),
attrs={"data-theme": "bootstrap-5"},
forward=["consent_group"],
forward=["consent_group", "upload_cycle"],
),
# "date_released": forms.SelectDateInput(),
# "date_released": forms.DateInput(),
Expand All @@ -122,11 +163,17 @@ def clean_upload_workspaces(self):
"""Validate that all UploadWorkspaces have the same consent group."""
data = self.cleaned_data["upload_workspaces"]
versions = set([x.consent_group for x in data])
upload_cycles = set([x.upload_cycle for x in data])
if len(versions) > 1:
self.add_error(
"upload_workspaces",
ValidationError(self.ERROR_UPLOAD_WORKSPACE_CONSENT),
)
if len(upload_cycles) > 1:
self.add_error(
"upload_workspaces",
ValidationError(self.ERROR_UPLOAD_CYCLE),
)
return data

def clean(self):
Expand All @@ -135,10 +182,14 @@ def clean(self):
# Make sure that the consent group specified matches the consent group for the upload_workspaces.
consent_group = cleaned_data.get("consent_group")
upload_workspaces = cleaned_data.get("upload_workspaces")
upload_cycle = cleaned_data.get("upload_cycle")
if consent_group and upload_workspaces:
# We only need to check the first workspace since the clean_upload_workspaces method checks
# that all upload_workspaces have the same consent.
if consent_group != upload_workspaces[0].consent_group:
raise ValidationError(self.ERROR_CONSENT_DOES_NOT_MATCH)

return cleaned_data
if upload_cycle and upload_workspaces:
# We only need to check the first workspace since the clean_upload_workspaces method checks
# that all upload_workspaces have the same upload_cycle.
if upload_cycle != upload_workspaces[0].upload_cycle:
raise ValidationError(self.ERROR_UPLOAD_CYCLE)
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Generated by Django 3.2.19 on 2023-06-13 18:19

from django.conf import settings
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import django_extensions.db.fields
import simple_history.models


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('gregor_anvil', '0009_unique_full_names'),
]

operations = [
migrations.CreateModel(
name='UploadCycle',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('cycle', models.PositiveIntegerField(help_text='The upload cycle represented by this model.', unique=True, validators=[django.core.validators.MinValueValidator(1)])),
('start_date', models.DateField(help_text='The start date of this upload cycle.')),
('end_date', models.DateField(help_text='The end date of this upload cycle.')),
('note', models.TextField(blank=True, help_text='Additional notes.')),
],
options={
'get_latest_by': 'modified',
'abstract': False,
},
),
migrations.CreateModel(
name='HistoricalUploadCycle',
fields=[
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('cycle', models.PositiveIntegerField(db_index=True, help_text='The upload cycle represented by this model.', validators=[django.core.validators.MinValueValidator(1)])),
('start_date', models.DateField(help_text='The start date of this upload cycle.')),
('end_date', models.DateField(help_text='The end date of this upload cycle.')),
('note', models.TextField(blank=True, help_text='Additional notes.')),
('history_id', models.AutoField(primary_key=True, serialize=False)),
('history_date', models.DateTimeField(db_index=True)),
('history_change_reason', models.CharField(max_length=100, null=True)),
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'historical upload cycle',
'verbose_name_plural': 'historical upload cycles',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': ('history_date', 'history_id'),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Generated by Django 3.2.19 on 2023-06-14 20:18

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('gregor_anvil', '0010_historicaluploadcycle_uploadcycle'),
]

operations = [
migrations.AddField(
model_name='combinedconsortiumdataworkspace',
name='upload_cycle',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='gregor_anvil.uploadcycle'),
),
migrations.AddField(
model_name='historicalcombinedconsortiumdataworkspace',
name='upload_cycle',
field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gregor_anvil.uploadcycle'),
),
migrations.AddField(
model_name='historicalreleaseworkspace',
name='upload_cycle',
field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gregor_anvil.uploadcycle'),
),
migrations.AddField(
model_name='historicaluploadworkspace',
name='upload_cycle',
field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gregor_anvil.uploadcycle'),
),
migrations.AddField(
model_name='releaseworkspace',
name='upload_cycle',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='gregor_anvil.uploadcycle'),
),
migrations.AddField(
model_name='uploadworkspace',
name='upload_cycle',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='gregor_anvil.uploadcycle'),
),
]
Loading

0 comments on commit e18d46a

Please sign in to comment.