diff --git a/hypha/apply/activity/models.py b/hypha/apply/activity/models.py index fcea47eb76..c21b1fd4aa 100644 --- a/hypha/apply/activity/models.py +++ b/hypha/apply/activity/models.py @@ -236,7 +236,7 @@ class Meta: def get_absolute_url(self): # coverup for both submission and project as source. submission_id = ( - self.source.submission.id + self.source.submission_id if hasattr(self.source, "submission") else self.source.id ) diff --git a/hypha/apply/dashboard/services.py b/hypha/apply/dashboard/services.py index 377f7296cb..58c64ce407 100644 --- a/hypha/apply/dashboard/services.py +++ b/hypha/apply/dashboard/services.py @@ -1,28 +1,28 @@ -from django.db.models import Count +from django.db.models import Count, Exists, OuterRef from hypha.apply.projects.models import PAFApprovals def get_paf_for_review(user, is_paf_approval_sequential): - """Return a list of paf approvals ready for user's review""" + """Return a queryset of paf approvals ready for user's review""" + user_groups = list(user.groups.all()) paf_approvals = PAFApprovals.objects.annotate( roles_count=Count("paf_reviewer_role__user_roles") ).filter( - roles_count=user.groups.count(), + roles_count=len(user_groups), approved=False, ) - for role in user.groups.all(): + for role in user_groups: paf_approvals = paf_approvals.filter(paf_reviewer_role__user_roles__id=role.id) if is_paf_approval_sequential: - all_matched_paf_approvals = list(paf_approvals) - for matched_paf_approval in all_matched_paf_approvals: - if matched_paf_approval.project.paf_approvals.filter( - paf_reviewer_role__sort_order__lt=matched_paf_approval.paf_reviewer_role.sort_order, - approved=False, - ).exists(): - paf_approvals = paf_approvals.exclude(id=matched_paf_approval.id) + blocking_step = PAFApprovals.objects.filter( + project=OuterRef("project"), + approved=False, + paf_reviewer_role__sort_order__lt=OuterRef("paf_reviewer_role__sort_order"), + ) + paf_approvals = paf_approvals.exclude(Exists(blocking_step)) return paf_approvals diff --git a/hypha/apply/dashboard/templates/dashboard/contracting_dashboard.html b/hypha/apply/dashboard/templates/dashboard/contracting_dashboard.html index b97e0bce6f..e803ce0737 100644 --- a/hypha/apply/dashboard/templates/dashboard/contracting_dashboard.html +++ b/hypha/apply/dashboard/templates/dashboard/contracting_dashboard.html @@ -41,7 +41,7 @@

- {% if projects_in_contracting.count %} + {% if PROJECTS_ENABLED and projects_in_contracting.count %} {% include "dashboard/includes/projects_in_contracting.html" with projects_in_contracting=projects_in_contracting %} {% endif %} diff --git a/hypha/apply/dashboard/templates/dashboard/finance_dashboard.html b/hypha/apply/dashboard/templates/dashboard/finance_dashboard.html index 6d5ba07de3..5228f186d8 100644 --- a/hypha/apply/dashboard/templates/dashboard/finance_dashboard.html +++ b/hypha/apply/dashboard/templates/dashboard/finance_dashboard.html @@ -92,7 +92,7 @@

{% trans 'Invoices' %}

{% trans "PAFs for review" %}

- {% if not paf_for_review.count %} + {% if PROJECTS_ENABLED and paf_for_review.count %} {% render_table paf_for_review.table %} {% else %}

diff --git a/hypha/apply/dashboard/views.py b/hypha/apply/dashboard/views.py index 19e1057ff9..563bd33620 100644 --- a/hypha/apply/dashboard/views.py +++ b/hypha/apply/dashboard/views.py @@ -71,8 +71,32 @@ def my_flagged(self, submissions): ) -class AdminDashboardView(MyFlaggedMixin, TemplateView): +class PAFReviewMixin: + paf_reviewer_role = None # set to a user attribute e.g. "is_apply_staff" + + def paf_for_review(self): + if not getattr(self.request.user, self.paf_reviewer_role, False): + return {"count": None, "table": None} + project_settings = ProjectSettings.for_request(self.request) + paf_approvals = list( + get_paf_for_review( + user=self.request.user, + is_paf_approval_sequential=project_settings.paf_approval_sequential, + ).select_related("project__submission__page", "paf_reviewer_role", "user") + ) + paf_table = PAFForReviewDashboardTable( + paf_approvals, prefix="paf-review-", order_by="-date_requested" + ) + RequestConfig(self.request, paginate=False).configure(paf_table) + return { + "count": len(paf_approvals), + "table": paf_table, + } + + +class AdminDashboardView(PAFReviewMixin, MyFlaggedMixin, TemplateView): template_name = "dashboard/staff_dashboard.html" + paf_reviewer_role = "is_apply_staff" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) @@ -97,25 +121,6 @@ def get_context_data(self, **kwargs): return context - def paf_for_review(self): - if not self.request.user.is_apply_staff: - return {"count": None, "table": None} - project_settings = ProjectSettings.for_request(self.request) - - paf_approvals = get_paf_for_review( - user=self.request.user, - is_paf_approval_sequential=project_settings.paf_approval_sequential, - ) - paf_table = PAFForReviewDashboardTable( - paf_approvals, prefix="paf-review-", order_by="-date_requested" - ) - RequestConfig(self.request, paginate=False).configure(paf_table) - - return { - "count": paf_approvals.count(), - "table": paf_table, - } - def my_tasks(self): tasks = render_task_templates_for_user(self.request, self.request.user) return { @@ -137,12 +142,16 @@ def awaiting_reviews(self, submissions): } def active_invoices(self): - invoices = Invoice.objects.filter( - project__lead=self.request.user, - ).in_progress() + invoices = list( + Invoice.objects.filter( + project__lead=self.request.user, + ) + .in_progress() + .select_related("project") + ) return { - "count": invoices.count(), + "count": len(invoices), "table": InvoiceDashboardTable(invoices), } @@ -154,12 +163,13 @@ def projects(self): ) limit = 10 + projects_count = projects.count() return { - "count": projects.count(), + "count": projects_count, "filterset": filterset, "table": ProjectsDashboardTable(data=projects[:limit], prefix="project-"), - "display_more": projects.count() > limit, + "display_more": projects_count > limit, "url": reverse("apply:projects:all"), } @@ -178,8 +188,9 @@ def rounds(self): } -class FinanceDashboardView(MyFlaggedMixin, TemplateView): +class FinanceDashboardView(PAFReviewMixin, MyFlaggedMixin, TemplateView): template_name = "dashboard/finance_dashboard.html" + paf_reviewer_role = "is_finance" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) @@ -196,25 +207,6 @@ def get_context_data(self, **kwargs): return context - def paf_for_review(self): - if not self.request.user.is_finance: - return {"count": None, "table": None} - project_settings = ProjectSettings.for_request(self.request) - - paf_approvals = get_paf_for_review( - user=self.request.user, - is_paf_approval_sequential=project_settings.paf_approval_sequential, - ) - paf_table = PAFForReviewDashboardTable( - paf_approvals, prefix="paf-review-", order_by="-date_requested" - ) - RequestConfig(self.request, paginate=False).configure(paf_table) - - return { - "count": paf_approvals.count(), - "table": paf_table, - } - def my_tasks(self): tasks = render_task_templates_for_user(self.request, self.request.user) return { @@ -223,22 +215,20 @@ def my_tasks(self): } def active_invoices(self): - invoices = Invoice.objects.for_finance_1() - + invoices = list(Invoice.objects.for_finance_1().select_related("project")) return { - "count": invoices.count(), + "count": len(invoices), "table": InvoiceDashboardTable(invoices), } def invoices_for_approval(self): - invoices = Invoice.objects.approved_by_staff() - - return {"count": invoices.count(), "table": InvoiceDashboardTable(invoices)} + invoices = list(Invoice.objects.approved_by_staff().select_related("project")) + return {"count": len(invoices), "table": InvoiceDashboardTable(invoices)} def invoices_to_convert(self): - invoices = Invoice.objects.waiting_to_convert() + invoices = list(Invoice.objects.waiting_to_convert().select_related("project")) return { - "count": invoices.count(), + "count": len(invoices), "table": InvoiceDashboardTable(invoices), } @@ -302,8 +292,9 @@ def awaiting_reviews(self, submissions): } -class ContractingDashboardView(MyFlaggedMixin, TemplateView): +class ContractingDashboardView(PAFReviewMixin, MyFlaggedMixin, TemplateView): template_name = "dashboard/contracting_dashboard.html" + paf_reviewer_role = "is_contracting" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) @@ -317,25 +308,6 @@ def get_context_data(self, **kwargs): return context - def paf_for_review(self): - if not self.request.user.is_contracting: - return {"count": None, "table": None} - project_settings = ProjectSettings.for_request(self.request) - - paf_approvals = get_paf_for_review( - user=self.request.user, - is_paf_approval_sequential=project_settings.paf_approval_sequential, - ) - paf_table = PAFForReviewDashboardTable( - paf_approvals, prefix="paf-review-", order_by="-date_requested" - ) - RequestConfig(self.request, paginate=False).configure(paf_table) - - return { - "count": paf_approvals.count(), - "table": paf_table, - } - def my_tasks(self): tasks = render_task_templates_for_user(self.request, self.request.user) return { @@ -357,22 +329,22 @@ def projects_in_contracting(self): }, } projects_in_contracting = Project.objects.in_contracting() - waiting_for_contract = projects_in_contracting.filter( - contracts__isnull=True - ).for_table() - waiting_for_contract_approval = projects_in_contracting.filter( - contracts__isnull=False - ).for_table() + waiting_for_contract = list( + projects_in_contracting.filter(contracts__isnull=True).for_table() + ) + waiting_for_contract_approval = list( + projects_in_contracting.filter(contracts__isnull=False).for_table() + ) return { - "count": projects_in_contracting.count(), + "count": len(waiting_for_contract) + len(waiting_for_contract_approval), "waiting_for_contract": { - "count": waiting_for_contract.count(), + "count": len(waiting_for_contract), "table": ProjectsDashboardTable( data=waiting_for_contract, prefix="project-waiting-contract-" ), }, "waiting_for_contract_approval": { - "count": waiting_for_contract_approval.count(), + "count": len(waiting_for_contract_approval), "table": ProjectsDashboardTable( data=waiting_for_contract_approval, prefix="project-waiting-approval-", @@ -389,13 +361,13 @@ def get_context_data(self, **kwargs): submissions = ApplicationSubmission.objects.all().for_table(self.request.user) # Submissions in community review phase - my_community_review, my_community_review = self.my_community_review( + my_community_review_qs, my_community_review_table = self.my_community_review( self.request.user, submissions ) context.update( { - "my_community_review": my_community_review, - "my_community_review_count": my_community_review.count(), + "my_community_review": my_community_review_table, + "my_community_review_count": my_community_review_qs.count(), "my_reviewed": get_preview_context( submissions.reviewed_by(self.request.user).order_by("-submit_time") ), @@ -444,26 +416,26 @@ def my_tasks(self): } def active_invoices(self): - active_invoices = ( + active_invoices = list( Invoice.objects.filter(project__user=self.request.user) .exclude(status__in=[PAID, DECLINED]) .order_by("-requested_at") ) - return {"count": active_invoices.count(), "data": active_invoices} + return {"count": len(active_invoices), "data": active_invoices} def historical_project_data(self): - historical_projects = ( + historical_projects = list( Project.objects.filter(user=self.request.user).complete().for_table() ) return { - "count": historical_projects.count(), + "count": len(historical_projects), "table": ProjectsDashboardTable( data=historical_projects, prefix="past-project-" ), } def historical_submission_data(self): - historical_submissions = ( + historical_submissions = list( ApplicationSubmission.objects.filter( user=self.request.user, ) @@ -472,8 +444,7 @@ def historical_submission_data(self): .for_table(self.request.user) ) return { - "count": historical_submissions.count(), - "submissions": historical_submissions, + "count": len(historical_submissions), "table": SubmissionsTable(data=historical_submissions), } diff --git a/hypha/apply/determinations/models.py b/hypha/apply/determinations/models.py index 0c8cad47f9..e0e046706d 100644 --- a/hypha/apply/determinations/models.py +++ b/hypha/apply/determinations/models.py @@ -135,7 +135,7 @@ def clean_outcome(self): def get_absolute_url(self): return reverse( "apply:submissions:determinations:detail", - args=(self.submission.id, self.id), + args=(self.submission_id, self.id), ) @property diff --git a/hypha/apply/determinations/views.py b/hypha/apply/determinations/views.py index abda7621c1..e33daf52c6 100644 --- a/hypha/apply/determinations/views.py +++ b/hypha/apply/determinations/views.py @@ -197,7 +197,7 @@ def form_valid(self, form): submissions = self.get_submissions() response = super().form_valid(form) determinations = { - determination.submission.id: determination + determination.submission_id: determination for determination in form.instances } sources = submissions.filter(id__in=list(determinations)) diff --git a/hypha/apply/funds/files.py b/hypha/apply/funds/files.py index 63f6b40cd9..582e34b264 100644 --- a/hypha/apply/funds/files.py +++ b/hypha/apply/funds/files.py @@ -30,12 +30,12 @@ def get_entity_id(self): if isinstance(self.instance, ApplicationRevision) or isinstance( self.instance, Project ): - entity_id = self.instance.submission.pk + entity_id = self.instance.submission_id elif isinstance(self.instance, Report) or isinstance(self.instance, ProjectSOW): - entity_id = self.instance.project.submission.pk + entity_id = self.instance.project.submission_id elif isinstance(self.instance, ReportVersion): # Reports are project documents. - entity_id = self.instance.report.project.submission.pk + entity_id = self.instance.report.project.submission_id return entity_id def generate_filename(self): diff --git a/hypha/apply/funds/models/application_revisions.py b/hypha/apply/funds/models/application_revisions.py index 516f91eaed..4ec15da38b 100644 --- a/hypha/apply/funds/models/application_revisions.py +++ b/hypha/apply/funds/models/application_revisions.py @@ -39,8 +39,8 @@ def get_compare_url_to_latest(self): return reverse( "funds:submissions:revisions:compare", kwargs={ - "submission_pk": self.submission.id, - "to": self.submission.live_revision.id, + "submission_pk": self.submission_id, + "to": self.submission.live_revision_id, "from": self.id, }, ) @@ -51,7 +51,7 @@ def get_absolute_url(self): return reverse( "funds:submissions:revisions:compare", kwargs={ - "submission_pk": self.submission.id, + "submission_pk": self.submission_id, "to": self.id, "from": previous_revision.id, }, diff --git a/hypha/apply/funds/models/submissions.py b/hypha/apply/funds/models/submissions.py index 528a4badfd..d8cd6d2c9a 100644 --- a/hypha/apply/funds/models/submissions.py +++ b/hypha/apply/funds/models/submissions.py @@ -247,6 +247,7 @@ def for_table(self, user): "previous__lead", ) .prefetch_related("screening_statuses") + .defer("search_data", "search_document") ) diff --git a/hypha/apply/funds/views/co_applicants.py b/hypha/apply/funds/views/co_applicants.py index 21efb2f940..cbd77c6641 100644 --- a/hypha/apply/funds/views/co_applicants.py +++ b/hypha/apply/funds/views/co_applicants.py @@ -203,7 +203,7 @@ def post(self, args, **kwargs): def get_success_url(self): return reverse_lazy( - "apply:submissions:detail", args=(self.invite.submission.pk,) + "apply:submissions:detail", args=(self.invite.submission_id,) ) diff --git a/hypha/apply/funds/views/revisions.py b/hypha/apply/funds/views/revisions.py index bf42991c25..0c316d9524 100644 --- a/hypha/apply/funds/views/revisions.py +++ b/hypha/apply/funds/views/revisions.py @@ -59,9 +59,14 @@ def get_queryset(self): An [`ApplicationRevision`][hypha.apply.funds.models.ApplicationRevision] QuerySet """ self.submission = get_object_or_404( - ApplicationSubmission, id=self.kwargs["submission_pk"] + ApplicationSubmission.objects.defer("form_data"), + id=self.kwargs["submission_pk"], + ) + self.queryset = ( + get_revisions(submission=self.submission) + .select_related("author", "submission") + .defer("form_data", "submission__form_data") ) - self.queryset = get_revisions(submission=self.submission) return super().get_queryset() diff --git a/hypha/apply/funds/views/submission_detail.py b/hypha/apply/funds/views/submission_detail.py index b9e4af7f41..eaf6847a62 100644 --- a/hypha/apply/funds/views/submission_detail.py +++ b/hypha/apply/funds/views/submission_detail.py @@ -53,6 +53,11 @@ class AdminSubmissionDetailView(ActivityContextMixin, DetailView): template_name_suffix = "_admin_detail" model = ApplicationSubmission + def get_object(self, queryset=None): + if not hasattr(self, "_object_cache"): + self._object_cache = super().get_object(queryset) + return self._object_cache + def dispatch(self, request, *args, **kwargs): submission = self.get_object() if submission.status == DRAFT_STATE and not submission.can_view_draft( @@ -114,6 +119,11 @@ class ReviewerSubmissionDetailView(ActivityContextMixin, DetailView): template_name_suffix = "_reviewer_detail" model = ApplicationSubmission + def get_object(self, queryset=None): + if not hasattr(self, "_object_cache"): + self._object_cache = super().get_object(queryset) + return self._object_cache + def dispatch(self, request, *args, **kwargs): submission = self.get_object() # If the requesting user submitted the application, return the Applicant view. @@ -147,6 +157,11 @@ class CommunitySubmissionDetailView(ActivityContextMixin, DetailView): template_name_suffix = "_community_detail" model = ApplicationSubmission + def get_object(self, queryset=None): + if not hasattr(self, "_object_cache"): + self._object_cache = super().get_object(queryset) + return self._object_cache + def dispatch(self, request, *args, **kwargs): submission = self.get_object() permission, _ = has_permission( @@ -172,7 +187,9 @@ class ApplicantSubmissionDetailView(ActivityContextMixin, DetailView): model = ApplicationSubmission def get_object(self): - return super().get_object().from_draft() + if not hasattr(self, "_object_cache"): + self._object_cache = super().get_object().from_draft() + return self._object_cache def dispatch(self, request, *args, **kwargs): submission = self.get_object() diff --git a/hypha/apply/funds/views/submission_edit.py b/hypha/apply/funds/views/submission_edit.py index 0fcad1e636..11683262a5 100644 --- a/hypha/apply/funds/views/submission_edit.py +++ b/hypha/apply/funds/views/submission_edit.py @@ -99,6 +99,13 @@ def render_preview(self, request: HttpRequest, form: BaseModelForm) -> HttpRespo context = self.get_context_data() return render(request, "funds/application_preview.html", context) + def get_object(self, queryset=None): + # Cache the object to avoid repeated DB queries + JSON deserialization + # (get_object is called in dispatch, subclass dispatch, and UpdateView.get/post) + if not hasattr(self, "_object_cache"): + self._object_cache = super().get_object(queryset) + return self._object_cache + def dispatch(self, request, *args, **kwargs): permission, _ = has_permission( "submission_edit", @@ -237,10 +244,9 @@ def get_form_kwargs(self): instance = kwargs.pop("instance").from_draft() initial = instance.raw_data for field_id in instance.file_field_ids: + original_value = initial.get(field_id) initial.pop(field_id + "-uploads", False) - initial[field_id] = self.get_placeholder_file( - instance.raw_data.get(field_id) - ) + initial[field_id] = self.get_placeholder_file(original_value) kwargs["initial"] = initial return kwargs diff --git a/hypha/apply/projects/models/payment.py b/hypha/apply/projects/models/payment.py index 50cb7b46dd..a04117c581 100644 --- a/hypha/apply/projects/models/payment.py +++ b/hypha/apply/projects/models/payment.py @@ -267,7 +267,7 @@ def value(self): def get_absolute_url(self): return reverse( "apply:projects:invoice-detail", - kwargs={"pk": self.project.submission.id, "invoice_pk": self.pk}, + kwargs={"pk": self.project.submission_id, "invoice_pk": self.pk}, ) @property @@ -298,7 +298,7 @@ def get_absolute_url(self): return reverse( "apply:projects:invoice-supporting-document", kwargs={ - "pk": self.invoice.project.submission.id, + "pk": self.invoice.project.submission_id, "invoice_pk": self.invoice.pk, "file_pk": self.pk, }, diff --git a/hypha/apply/projects/models/project.py b/hypha/apply/projects/models/project.py index cea5d5d10e..e3b6484694 100644 --- a/hypha/apply/projects/models/project.py +++ b/hypha/apply/projects/models/project.py @@ -176,6 +176,7 @@ def for_table(self): "submission__page", "lead", ) + .defer("form_data", "form_fields") ) def for_reporting_table(self): @@ -453,7 +454,7 @@ def editable(self): return False def get_absolute_url(self): - return reverse("funds:submissions:project", args=[self.submission.id]) + return reverse("funds:submissions:project", args=[self.submission_id]) @property def can_make_approval(self): @@ -700,7 +701,7 @@ def __str__(self): def get_absolute_url(self): return reverse( - "apply:projects:contract", args=[self.project.submission.id, self.pk] + "apply:projects:contract", args=[self.project.submission_id, self.pk] ) diff --git a/hypha/apply/projects/tables.py b/hypha/apply/projects/tables.py index 6a92275fea..cacab9851d 100644 --- a/hypha/apply/projects/tables.py +++ b/hypha/apply/projects/tables.py @@ -28,7 +28,7 @@ class BaseInvoiceTable(tables.Table): invoice_number = tables.LinkColumn( "funds:projects:invoice-detail", verbose_name=_("Invoice #"), - args=[tables.utils.A("project__submission__pk"), tables.utils.A("pk")], + args=[tables.utils.A("project__submission_id"), tables.utils.A("pk")], attrs={ "td": { "class": "js-title", # using title as class because of batch-actions.js @@ -50,7 +50,7 @@ class BaseInvoiceTable(tables.Table): class Meta: row_attrs = { "onclick": lambda record: ( - f"window.location.href='{reverse('funds:projects:invoice-detail', args=[record.project.submission.pk, record.pk])}'" + f"window.location.href='{reverse('funds:projects:invoice-detail', args=[record.project.submission_id, record.pk])}'" ), "class": "table-row-link", "role": "button", diff --git a/hypha/apply/projects/views/payment.py b/hypha/apply/projects/views/payment.py index 884dbc4493..0c3b94bcd2 100644 --- a/hypha/apply/projects/views/payment.py +++ b/hypha/apply/projects/views/payment.py @@ -372,7 +372,7 @@ def post(self, request, *args, **kwargs): if "delete" in form.data: return redirect( "apply:projects:invoice-delete", - pk=self.object.project.submission.id, + pk=self.object.project.submission_id, invoice_pk=self.object.id, ) if form.is_valid(): @@ -585,6 +585,9 @@ class InvoiceListView(SingleTableMixin, FilterView, DelegateableListView): table_class = AdminInvoiceListTable template_name = "application_projects/invoice_list.html" + def get_queryset(self): + return super().get_queryset().select_related("project", "project__user") + def get_table_class(self): if self.request.user.is_finance: return FinanceInvoiceTable diff --git a/hypha/apply/projects/views/project.py b/hypha/apply/projects/views/project.py index 8e89a9c5ca..cb0aecd6e6 100644 --- a/hypha/apply/projects/views/project.py +++ b/hypha/apply/projects/views/project.py @@ -1627,6 +1627,11 @@ def post(self, *args, **kwargs): class BaseProjectDetailView(ReportingMixin, ProjectBySubmissionIdMixin, DetailView): + def get_object(self, queryset=None): + if not hasattr(self, "_object_cache"): + self._object_cache = super().get_object() + return self._object_cache + def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["statuses"] = get_project_status_choices() @@ -1995,7 +2000,7 @@ def get_paf_download_context(self): context["submission"] = self.object.submission context["submission_link"] = self.request.build_absolute_uri( reverse( - "apply:submissions:detail", kwargs={"pk": self.object.submission.id} + "apply:submissions:detail", kwargs={"pk": self.object.submission_id} ) ) context["supporting_documents"] = self.get_supporting_documents(self.object) @@ -2022,7 +2027,7 @@ def get_supporting_documents(self, project): documents_dict[packet_file.title] = self.request.build_absolute_uri( reverse( "apply:projects:document", - kwargs={"pk": project.submission.id, "file_pk": packet_file.id}, + kwargs={"pk": project.submission_id, "file_pk": packet_file.id}, ) ) return documents_dict diff --git a/hypha/apply/review/models.py b/hypha/apply/review/models.py index 9abeec482b..ef26365089 100644 --- a/hypha/apply/review/models.py +++ b/hypha/apply/review/models.py @@ -199,7 +199,7 @@ def get_absolute_url(self): return reverse( "apply:submissions:reviews:review", args=( - self.submission.pk, + self.submission_id, self.id, ), ) diff --git a/hypha/apply/review/views.py b/hypha/apply/review/views.py index 4117d7bdb8..e2902691bd 100644 --- a/hypha/apply/review/views.py +++ b/hypha/apply/review/views.py @@ -116,7 +116,7 @@ def form_valid(self, form): def get_success_url(self): review = self.get_object() - return reverse_lazy("funds:submissions:detail", args=(review.submission.id,)) + return reverse_lazy("funds:submissions:detail", args=(review.submission_id,)) @method_decorator(login_required, name="dispatch") @@ -306,7 +306,7 @@ def dispatch(self, request, *args, **kwargs): if review.is_draft: return HttpResponseRedirect( reverse_lazy( - "apply:submissions:reviews:form", args=(review.submission.id,) + "apply:submissions:reviews:form", args=(review.submission_id,) ) ) @@ -375,7 +375,7 @@ def form_valid(self, form): if opinion.opinion == DISAGREE: return HttpResponseRedirect( reverse_lazy( - "apply:submissions:reviews:form", args=(self.review.submission.pk,) + "apply:submissions:reviews:form", args=(self.review.submission_id,) ) ) else: @@ -513,7 +513,7 @@ def form_valid(self, form): def get_success_url(self): review = self.get_object() - return reverse_lazy("funds:submissions:detail", args=(review.submission.id,)) + return reverse_lazy("funds:submissions:detail", args=(review.submission_id,)) @method_decorator(login_required, name="dispatch") @@ -540,4 +540,4 @@ def delete(self, request, *args, **kwargs): def get_success_url(self): review = self.review_opinion.review - return reverse_lazy("funds:submissions:detail", args=(review.submission.id,)) + return reverse_lazy("funds:submissions:detail", args=(review.submission_id,)) diff --git a/hypha/apply/users/tokens.py b/hypha/apply/users/tokens.py index 832b50d0bd..915374bddf 100644 --- a/hypha/apply/users/tokens.py +++ b/hypha/apply/users/tokens.py @@ -108,5 +108,5 @@ def _make_hash_value(self, invite, timestamp): attempts using the reset token, provided the secret isn't compromised. """ return ( - f"{invite.pk}{invite.submission.pk}{timestamp}{invite.invited_user_email}" + f"{invite.pk}{invite.submission_id}{timestamp}{invite.invited_user_email}" )