diff --git a/study_registration/budgets/templates/budgets/_study_detail_budgets.html b/study_registration/budgets/templates/budgets/_study_detail_budgets.html index 13f6ca2648a6b67014e8c53c5eddc3990d6f3036..9730172cfbddc9266a18a0ed558be10b4e16d1bd 100644 --- a/study_registration/budgets/templates/budgets/_study_detail_budgets.html +++ b/study_registration/budgets/templates/budgets/_study_detail_budgets.html @@ -5,7 +5,7 @@

{% translate 'Budgets' %}

{% if is_owner %}
- {% translate 'Add budget' %} + {% translate 'Add budget' %}
{% endif %} @@ -13,8 +13,8 @@ {% for budget in study.budget_set.all %} {% if is_owner %}
- {% translate 'Update' %} - {% translate 'Delete' %} + {% translate 'Update' %} + {% translate 'Delete' %}
{% endif %} {{ budget.expected }} € diff --git a/study_registration/budgets/templates/budgets/budget_base.html b/study_registration/budgets/templates/budgets/budget_base.html index e24fe6fc349f37163bff85f562ad943e77d8daf6..fe1e97f2c0235d0e5037da97b34a61c63878a140 100644 --- a/study_registration/budgets/templates/budgets/budget_base.html +++ b/study_registration/budgets/templates/budgets/budget_base.html @@ -13,8 +13,8 @@ {% block breadcrumbs %} {{ block.super }} {% if budget %} - + {% else %} - + {% endif %} {% endblock %} diff --git a/study_registration/budgets/templates/budgets/budget_confirm_delete.html b/study_registration/budgets/templates/budgets/budget_confirm_delete.html index 5a052d6470e0e11100f021194ca2797ec22990ff..db62d578d661e6dcd04bf54b04e4ef72d55847d9 100644 --- a/study_registration/budgets/templates/budgets/budget_confirm_delete.html +++ b/study_registration/budgets/templates/budgets/budget_confirm_delete.html @@ -5,7 +5,7 @@ {% block breadcrumbs %} {{ block.super }} - + {% endblock %} {% block content %} @@ -17,7 +17,7 @@ {% endblocktranslate %}

- {% translate 'Cancel' %} + {% translate 'Cancel' %}
diff --git a/study_registration/budgets/templates/budgets/budget_form.html b/study_registration/budgets/templates/budgets/budget_form.html index b1e8ef0e55c3059292e8b0a54d8e622359f4028f..08bb747f3b4980c25bde52ba59758845fd516409 100644 --- a/study_registration/budgets/templates/budgets/budget_form.html +++ b/study_registration/budgets/templates/budgets/budget_form.html @@ -11,7 +11,7 @@ {% bootstrap_field form.approved_by %}
- {% translate 'Cancel' %} + {% translate 'Cancel' %}
diff --git a/study_registration/datasets/templates/datasets/_study_detail_datasets.html b/study_registration/datasets/templates/datasets/_study_detail_datasets.html index 4cd41a0ef4137556ff82b90bb00d41aafabdcde0..4a1b40aa2138d1af0ba2ebf3be4ac7ea49396e85 100644 --- a/study_registration/datasets/templates/datasets/_study_detail_datasets.html +++ b/study_registration/datasets/templates/datasets/_study_detail_datasets.html @@ -5,7 +5,7 @@

{% translate 'Raw data folders' %}

{% if is_owner %}
- {% translate 'Add data folder' %} + {% translate 'Add data folder' %}
{% endif %} @@ -13,8 +13,8 @@ {% for dataset in study.dataset_set.all %} {% if is_owner %}
- {% translate 'Update' %} - {% translate 'Delete' %} + {% translate 'Update' %} + {% translate 'Delete' %}
{% endif %}
diff --git a/study_registration/datasets/templates/datasets/dataset_base.html b/study_registration/datasets/templates/datasets/dataset_base.html index f24de64d25c402a9c10e703f4479717fb2ff26c7..fc2d2958964db82176d3bff0800850bf5640a530 100644 --- a/study_registration/datasets/templates/datasets/dataset_base.html +++ b/study_registration/datasets/templates/datasets/dataset_base.html @@ -13,8 +13,8 @@ {% block breadcrumbs %} {{ block.super }} {% if dataset %} - + {% else %} - + {% endif %} {% endblock %} diff --git a/study_registration/datasets/templates/datasets/dataset_confirm_delete.html b/study_registration/datasets/templates/datasets/dataset_confirm_delete.html index 337594a94272d3a80bde19fb9363de0604dba504..de5e10ed38133a68e00c550739ebd3731fde11d5 100644 --- a/study_registration/datasets/templates/datasets/dataset_confirm_delete.html +++ b/study_registration/datasets/templates/datasets/dataset_confirm_delete.html @@ -5,7 +5,7 @@ {% block breadcrumbs %} {{ block.super }} - + {% endblock %} {% block content %} @@ -17,7 +17,7 @@ {% endblocktranslate %}

- {% translate 'Cancel' %} + {% translate 'Cancel' %}
diff --git a/study_registration/datasets/templates/datasets/dataset_form.html b/study_registration/datasets/templates/datasets/dataset_form.html index 58934926d2ca5011eef7213108562f408d91d677..085df162b82b67cd22d95a1bc2be27e75209deb4 100644 --- a/study_registration/datasets/templates/datasets/dataset_form.html +++ b/study_registration/datasets/templates/datasets/dataset_form.html @@ -48,7 +48,7 @@
- {% translate 'Cancel' %} + {% translate 'Cancel' %}
diff --git a/study_registration/deployments/api.py b/study_registration/deployments/api.py index 64d5bdcbe074d4905a8208d73290565c9dd353dd..65b2bc0360437c7ae3bdc867223253505ddeccfa 100644 --- a/study_registration/deployments/api.py +++ b/study_registration/deployments/api.py @@ -12,7 +12,7 @@ class DeploymentsApiView(View): return { 'study_identifier': str(deployment.study), 'study_url': self.request.build_absolute_uri( - reverse('studies:api', args=[deployment.study.pk]) + reverse('studies:api', args=[deployment.study.pk, deployment.study.short_title]) ), 'git_repo': deployment.git_repo, 'git_ref': deployment.git_ref, diff --git a/study_registration/deployments/templates/deployments/_study_detail_deployments.html b/study_registration/deployments/templates/deployments/_study_detail_deployments.html index e8f2083e60ead988aa42a297bb324b0bb09ebe89..cf37d4b51458d7127f3b222854cb8b98e40a57c5 100644 --- a/study_registration/deployments/templates/deployments/_study_detail_deployments.html +++ b/study_registration/deployments/templates/deployments/_study_detail_deployments.html @@ -5,7 +5,7 @@

{% translate 'Deployments' %}

{% if is_owner %}
- {% translate 'Add deployment' %} + {% translate 'Add deployment' %}
{% endif %} @@ -13,8 +13,8 @@ {% for deployment in study.deployment_set.all %} {% if is_owner %}
- {% translate 'Update' %} - {% translate 'Delete' %} + {% translate 'Update' %} + {% translate 'Delete' %}
{% endif %} {{ deployment }} diff --git a/study_registration/deployments/templates/deployments/deployment_base.html b/study_registration/deployments/templates/deployments/deployment_base.html index 3f590b97bd5d3db7d2ae4e9193034f9c72f7e320..41677b5336442fcac5535a6ba4fb996d4d6db025 100644 --- a/study_registration/deployments/templates/deployments/deployment_base.html +++ b/study_registration/deployments/templates/deployments/deployment_base.html @@ -13,8 +13,8 @@ {% block breadcrumbs %} {{ block.super }} {% if deployment %} - + {% else %} - + {% endif %} {% endblock %} diff --git a/study_registration/deployments/templates/deployments/deployment_confirm_delete.html b/study_registration/deployments/templates/deployments/deployment_confirm_delete.html index 870fb18d6ad8fd542b24f6b8cb1818ca21f58629..fefe39764158e5b69e1ecae33df5b41eaf7a6f71 100644 --- a/study_registration/deployments/templates/deployments/deployment_confirm_delete.html +++ b/study_registration/deployments/templates/deployments/deployment_confirm_delete.html @@ -5,7 +5,7 @@ {% block breadcrumbs %} {{ block.super }} - + {% endblock %} {% block content %} @@ -17,7 +17,7 @@ {% endblocktranslate %}

- {% translate 'Cancel' %} + {% translate 'Cancel' %}
diff --git a/study_registration/deployments/templates/deployments/deployment_form.html b/study_registration/deployments/templates/deployments/deployment_form.html index 67b809b65b03edbd15a533079dbb3452bf4fcc8d..a9b53cd647dd8006fd6a4272abfc89e1b896c93b 100644 --- a/study_registration/deployments/templates/deployments/deployment_form.html +++ b/study_registration/deployments/templates/deployments/deployment_form.html @@ -14,7 +14,7 @@ {% bootstrap_field form.enddate %}
- {% translate 'Cancel' %} + {% translate 'Cancel' %}
diff --git a/study_registration/ethics/models.py b/study_registration/ethics/models.py index 0a922eefccf9daa08b05d0ad71a76e75349ae457..1d7d813c4939db5bedfa668dd8af17a64073b748 100644 --- a/study_registration/ethics/models.py +++ b/study_registration/ethics/models.py @@ -15,7 +15,7 @@ class EthicsBoard(models.Model): def get_upload_path(instance, filename): - return '{}/ethics/{}'.format(instance.study.pk, filename) + return '{}-{}/ethics/{}'.format(instance.study.pk, instance.study.short_title, filename) class EthicsApplication(models.Model): diff --git a/study_registration/ethics/templates/ethics/_study_detail_ethics.html b/study_registration/ethics/templates/ethics/_study_detail_ethics.html index 10fcf441af99836484ab73c3cb8c5cba4dd300b3..885b744eb4e667872210b39e6d6c7beb0d2d9b35 100644 --- a/study_registration/ethics/templates/ethics/_study_detail_ethics.html +++ b/study_registration/ethics/templates/ethics/_study_detail_ethics.html @@ -5,7 +5,7 @@

{% translate 'Ethics applications' %}

{% if is_owner %}
- {% translate 'Add application' %} + {% translate 'Add application' %}
{% endif %} @@ -13,8 +13,8 @@ {% for application in study.ethicsapplication_set.all %} {% if is_owner %}
- {% translate 'Update' %} - {% translate 'Delete' %} + {% translate 'Update' %} + {% translate 'Delete' %}
{% endif %}
diff --git a/study_registration/ethics/templates/ethics/ethicsapplication_base.html b/study_registration/ethics/templates/ethics/ethicsapplication_base.html index 2e3018bc2db40762fb1b9e949df8d575e86d5272..3fca97df5372117379dcdda7a2678537abc038f2 100644 --- a/study_registration/ethics/templates/ethics/ethicsapplication_base.html +++ b/study_registration/ethics/templates/ethics/ethicsapplication_base.html @@ -13,8 +13,8 @@ {% block breadcrumbs %} {{ block.super }} {% if ethicsapplication %} - + {% else %} - + {% endif %} {% endblock %} diff --git a/study_registration/ethics/templates/ethics/ethicsapplication_confirm_delete.html b/study_registration/ethics/templates/ethics/ethicsapplication_confirm_delete.html index ca15bd70ed8818d108d9578510d6281ba1143b68..188c71522c92425a1b8f6e0fc793fa7b64bc1114 100644 --- a/study_registration/ethics/templates/ethics/ethicsapplication_confirm_delete.html +++ b/study_registration/ethics/templates/ethics/ethicsapplication_confirm_delete.html @@ -5,7 +5,7 @@ {% block breadcrumbs %} {{ block.super }} - + {% endblock %} {% block content %} @@ -17,7 +17,7 @@ {% endblocktranslate %}

- {% translate 'Cancel' %} + {% translate 'Cancel' %}
diff --git a/study_registration/ethics/templates/ethics/ethicsapplication_form.html b/study_registration/ethics/templates/ethics/ethicsapplication_form.html index ba9f0dea6d1b06b948b58b0ac8c61d88fd671f05..afabf2d11223093f3a6ad0921241ec00224f0fb5 100644 --- a/study_registration/ethics/templates/ethics/ethicsapplication_form.html +++ b/study_registration/ethics/templates/ethics/ethicsapplication_form.html @@ -12,7 +12,7 @@ {% bootstrap_field form.approval %} diff --git a/study_registration/publications/templates/publications/_study_detail_publications.html b/study_registration/publications/templates/publications/_study_detail_publications.html index fa0b6d1c889b85441ad477afa6dde1a4f4626f4a..7710b50249d047c75fcc79378778da13870c68c8 100644 --- a/study_registration/publications/templates/publications/_study_detail_publications.html +++ b/study_registration/publications/templates/publications/_study_detail_publications.html @@ -5,7 +5,7 @@

{% translate 'Publications' %}

{% if is_owner %} {% endif %}
@@ -15,8 +15,8 @@
  • {% if is_owner %} {% endif %} {{ publication.title }}. diff --git a/study_registration/publications/templates/publications/publication_base.html b/study_registration/publications/templates/publications/publication_base.html index ddbbd6650e002369e21d145acc92f74f30815a76..37460ed69ef3d4ce93f2af5ff3ad3a1447a79dab 100644 --- a/study_registration/publications/templates/publications/publication_base.html +++ b/study_registration/publications/templates/publications/publication_base.html @@ -13,8 +13,8 @@ {% block breadcrumbs %} {{ block.super }} {% if publication %} -
  • + {% else %} - + {% endif %} {% endblock %} diff --git a/study_registration/publications/templates/publications/publication_confirm_delete.html b/study_registration/publications/templates/publications/publication_confirm_delete.html index a060d11b631df6be1cc9ede9850bcea51b0f1666..53d5b368278c60e0b98be436b0d1bbaf4dad2a9d 100644 --- a/study_registration/publications/templates/publications/publication_confirm_delete.html +++ b/study_registration/publications/templates/publications/publication_confirm_delete.html @@ -5,7 +5,7 @@ {% block breadcrumbs %} {{ block.super }} - + {% endblock %} {% block content %} @@ -17,7 +17,7 @@ {% endblocktranslate %}

    - {% translate 'Cancel' %} + {% translate 'Cancel' %}
    diff --git a/study_registration/publications/templates/publications/publication_form.html b/study_registration/publications/templates/publications/publication_form.html index e56d4304a5227684ec1b96b153fb64400381fa46..43561c6c48ad688d202828a2e421b1bab27bc8e6 100644 --- a/study_registration/publications/templates/publications/publication_form.html +++ b/study_registration/publications/templates/publications/publication_form.html @@ -13,7 +13,7 @@ {% bootstrap_field form.year %}
    - {% translate 'Cancel' %} + {% translate 'Cancel' %}
    diff --git a/study_registration/studies/mixins.py b/study_registration/studies/mixins.py index 9dd257d60e9a94e34a9fd6365ceda2d799f8bbe6..ba5be50734f5c760047cd8c90ead553e31d229ac 100644 --- a/study_registration/studies/mixins.py +++ b/study_registration/studies/mixins.py @@ -1,10 +1,25 @@ from django.contrib.auth.mixins import LoginRequiredMixin +from django.http.response import HttpResponseRedirectBase from django.shortcuts import get_object_or_404 from django.urls import reverse from .models import Study +class HttpResponseRedirect(HttpResponseRedirectBase): + status_code = 307 # instead of 302 to keep POST requests + + +def redirect_to_correct_study_id(request, study): + parts = request.path.split('/') + parts[2] = '{}-{}'.format(study.pk, study.short_title) + url = '/'.join(parts) + query = request.GET.urlencode() + if query: + url += '?' + query + return HttpResponseRedirect(url) + + class StudyAspectMixin(LoginRequiredMixin): def dispatch(self, request, **kwargs): if not request.user.is_authenticated: @@ -13,6 +28,8 @@ class StudyAspectMixin(LoginRequiredMixin): self.study = get_object_or_404(Study, pk=kwargs['study_pk']) else: self.study = get_object_or_404(Study, pk=kwargs['study_pk'], owners=request.user) + if self.study.short_title != kwargs['study_short']: + return redirect_to_correct_study_id(request, self.study) return super().dispatch(request, **kwargs) def get_object(self): diff --git a/study_registration/studies/templates/studies/_study_detail_general.html b/study_registration/studies/templates/studies/_study_detail_general.html index 920fe12b44e7433b874cd812dc5594a71275574b..2d98c76e100a6bcbc4b64e309b3fdaf181709fa4 100644 --- a/study_registration/studies/templates/studies/_study_detail_general.html +++ b/study_registration/studies/templates/studies/_study_detail_general.html @@ -5,8 +5,8 @@

    {{ study.title }}

    {% if is_owner %}
    - {% translate 'Update' %} - {% translate 'Delete Study' %} + {% translate 'Update' %} + {% translate 'Delete Study' %}
    {% endif %} @@ -33,7 +33,7 @@
    {% translate 'Study ID' %}
    -
    {{ study|display:'id' }}
    +
    {{ study }}
    {{ study|verbose_name:'created_at' }}
    {{ study|display:'created_at' }}
    diff --git a/study_registration/studies/templates/studies/study_confirm_delete.html b/study_registration/studies/templates/studies/study_confirm_delete.html index 269e73d4a0a1a2d2a39ec71760fd018abf919711..e3f035978dd4909ed3e08f8779266d8692d794dc 100644 --- a/study_registration/studies/templates/studies/study_confirm_delete.html +++ b/study_registration/studies/templates/studies/study_confirm_delete.html @@ -5,7 +5,7 @@ {% block breadcrumbs %} {{ block.super }} - + {% endblock %} {% block content %} @@ -17,7 +17,7 @@ {% endblocktranslate %}

    - {% translate 'Cancel' %} + {% translate 'Cancel' %}
    diff --git a/study_registration/studies/templates/studies/study_form.html b/study_registration/studies/templates/studies/study_form.html index 77c6ab71e59499be6e43d586c2e6fa95f96976c9..d1418e2b2c032785e863373169cb503cd689ddb5 100644 --- a/study_registration/studies/templates/studies/study_form.html +++ b/study_registration/studies/templates/studies/study_form.html @@ -13,7 +13,7 @@ {% block breadcrumbs %} {{ block.super }} {% if study %} - + {% else %} {% endif %} @@ -45,7 +45,7 @@
    {% if study %} - {% translate 'Cancel' %} + {% translate 'Cancel' %} {% else %} {% translate 'Cancel' %} {% endif %} diff --git a/study_registration/studies/templates/studies/study_list.html b/study_registration/studies/templates/studies/study_list.html index a2b44c4a3d92ec6dfeefc5ea552bda050ce869fd..d7b891002812e4d6156327fe8ba0fd9acef03fa0 100644 --- a/study_registration/studies/templates/studies/study_list.html +++ b/study_registration/studies/templates/studies/study_list.html @@ -11,7 +11,7 @@ {% for study in object_list %}
  • -

    {{ study.title }}

    +

    {{ study.title }}

    {% icon 'user' %} {{ study.contact_person.get_full_name }} {% for keyword in study.keyword_set.all %} {{ keyword }} diff --git a/study_registration/studies/urls.py b/study_registration/studies/urls.py index a6d1c905a217525bf6db11910ccd24ebd641ec71..46dce1ba533425dcfa315f56759171c2b75b74e1 100644 --- a/study_registration/studies/urls.py +++ b/study_registration/studies/urls.py @@ -13,8 +13,8 @@ urlpatterns = [ path('', StudyListView.as_view(), name='list'), path('mine/', MyStudiesView.as_view(), name='mine'), path('new/', StudyCreateView.as_view(), name='create'), - path('/', StudyDetailView.as_view(), name='detail'), - path('.json', StudyApiView.as_view(), name='api'), - path('/update/', StudyUpdateView.as_view(), name='update'), - path('/delete/', StudyDeleteView.as_view(), name='delete'), + path('-/', StudyDetailView.as_view(), name='detail'), + path('-.json', StudyApiView.as_view(), name='api'), + path('-/update/', StudyUpdateView.as_view(), name='update'), + path('-/delete/', StudyDeleteView.as_view(), name='delete'), ] diff --git a/study_registration/studies/views.py b/study_registration/studies/views.py index bb2a4a1a4ddba013575f391a6d05c4d38e03ad77..5f5823d228e57e01a98bb52106d2d8815f151f05 100644 --- a/study_registration/studies/views.py +++ b/study_registration/studies/views.py @@ -12,6 +12,7 @@ from django.views.generic import UpdateView from .forms import StudyForm from .models import Study +from .mixins import redirect_to_correct_study_id def split_with_quotes(s): @@ -109,6 +110,12 @@ class MyStudiesView(LoginRequiredMixin, RedirectView): class StudyDetailView(DetailView): model = Study + def dispatch(self, request, **kwargs): + study = super().get_object() + if study.short_title != self.kwargs['short']: + return redirect_to_correct_study_id(self.request, study) + return super().dispatch(request, **kwargs) + def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['is_owner'] = ( @@ -149,6 +156,12 @@ class StudyUpdateView(OwnerRequiredMixin, UpdateView): model = Study form_class = StudyForm + def dispatch(self, request, **kwargs): + study = super().get_object() + if study.short_title != self.kwargs['short']: + return redirect_to_correct_study_id(self.request, study) + return super().dispatch(request, **kwargs) + def get_success_url(self): return reverse('studies:detail', args=[self.object.pk]) @@ -156,5 +169,11 @@ class StudyUpdateView(OwnerRequiredMixin, UpdateView): class StudyDeleteView(OwnerRequiredMixin, DeleteView): model = Study + def dispatch(self, request, **kwargs): + study = super().get_object() + if study.short_title != self.kwargs['short']: + return redirect_to_correct_study_id(self.request, study) + return super().dispatch(request, **kwargs) + def get_success_url(self): return reverse('studies:list') diff --git a/study_registration/templates/base.html b/study_registration/templates/base.html index 92e37a4b1a469c26409dba14bf1f2ce661ac0df9..c0320db5ae68106dcd74c99d437ec8e4fac70711 100644 --- a/study_registration/templates/base.html +++ b/study_registration/templates/base.html @@ -41,7 +41,7 @@
    diff --git a/study_registration/urls.py b/study_registration/urls.py index 655f19aa91e141d07f606d96b4e3877f44aa54d5..446d8938fd265c18ff844aafec2fd52f20254237 100644 --- a/study_registration/urls.py +++ b/study_registration/urls.py @@ -20,23 +20,23 @@ urlpatterns = [ template_name='bootstrap_theme.css', content_type='text/css' ), name='bootstrap-theme'), path( - 'studies//publications/', + 'studies/-/publications/', include('study_registration.publications.urls', namespace='publications'), ), path( - 'studies//ethics/', + 'studies/-/ethics/', include('study_registration.ethics.urls', namespace='ethics'), ), path( - 'studies//datasets/', + 'studies/-/datasets/', include('study_registration.datasets.urls', namespace='datasets'), ), path( - 'studies//budgets/', + 'studies/-/budgets/', include('study_registration.budgets.urls', namespace='budgets'), ), path( - 'studies//deployments/', + 'studies/-/deployments/', include(deployment_urls, namespace='deployments'), ), path('api/deployments/', include(deployment_urls.apipatterns)),