diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc
index 5c1f0c4..09ca623 100644
Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ
diff --git a/core/templates/core/job_list.html b/core/templates/core/job_list.html
index a8e6f80..9327b35 100644
--- a/core/templates/core/job_list.html
+++ b/core/templates/core/job_list.html
@@ -44,6 +44,9 @@
+
@@ -59,6 +62,19 @@
{% endfor %}
+ {% if jobs.has_other_pages %}
+
+ {% endif %}
{% else %}
diff --git a/core/templates/core/ops_dashboard.html b/core/templates/core/ops_dashboard.html
index 92ce73a..84d8c4d 100644
--- a/core/templates/core/ops_dashboard.html
+++ b/core/templates/core/ops_dashboard.html
@@ -44,6 +44,9 @@
+
@@ -81,6 +84,19 @@
+ {% if sources.has_other_pages %}
+
+ {% endif %}
{% else %}
No sources yet. Register the first portal, agency, or company careers page.
{% endif %}
diff --git a/core/views.py b/core/views.py
index c87ced7..733eebb 100644
--- a/core/views.py
+++ b/core/views.py
@@ -1,5 +1,6 @@
from django.contrib import messages
from django.db.models import Count, Q
+from django.core.paginator import Paginator
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import timezone
@@ -96,20 +97,28 @@ def job_list(request):
family = request.GET.get("family", "").strip()
source_status = request.GET.get("source_status", "").strip()
- jobs = JobPosting.objects.select_related("source").filter(is_active=True)
+ jobs_qs = JobPosting.objects.select_related("source").filter(is_active=True)
if query:
- jobs = jobs.filter(
+ jobs_qs = jobs_qs.filter(
Q(title__icontains=query)
| Q(company__icontains=query)
| Q(location__icontains=query)
| Q(description__icontains=query)
)
if contract:
- jobs = jobs.filter(contract_type=contract)
+ jobs_qs = jobs_qs.filter(contract_type=contract)
if family:
- jobs = jobs.filter(source__family=family)
+ jobs_qs = jobs_qs.filter(source__family=family)
if source_status:
- jobs = jobs.filter(source__status=source_status)
+ jobs_qs = jobs_qs.filter(source__status=source_status)
+
+ paginator = Paginator(jobs_qs, 9)
+ page_number = request.GET.get("page")
+ jobs = paginator.get_page(page_number)
+
+ filters = request.GET.copy()
+ filters.pop("page", None)
+ current_filters_qs = filters.urlencode()
context = {
**_meta("Search Job Offers", "Search normalized job offers collected for Dijon and nearby opportunities."),
@@ -121,7 +130,8 @@ def job_list(request):
"contract_choices": JobPosting.ContractType.choices,
"family_choices": JobSource.Family.choices,
"source_status_choices": JobSource.Status.choices,
- "result_count": jobs.count(),
+ "result_count": jobs_qs.count(),
+ "current_filters_qs": current_filters_qs,
}
return render(request, "core/job_list.html", context)
@@ -144,13 +154,21 @@ def ops_dashboard(request):
family = request.GET.get("family", "").strip()
status = request.GET.get("status", "").strip()
- sources = JobSource.objects.annotate(job_total=Count("jobs")).order_by("family", "name")
+ sources_qs = JobSource.objects.annotate(job_total=Count("jobs")).order_by("family", "name")
if query:
- sources = sources.filter(Q(name__icontains=query) | Q(owner__icontains=query) | Q(url__icontains=query))
+ sources_qs = sources_qs.filter(Q(name__icontains=query) | Q(owner__icontains=query) | Q(url__icontains=query))
if family:
- sources = sources.filter(family=family)
+ sources_qs = sources_qs.filter(family=family)
if status:
- sources = sources.filter(status=status)
+ sources_qs = sources_qs.filter(status=status)
+
+ paginator = Paginator(sources_qs, 8)
+ page_number = request.GET.get("page")
+ sources = paginator.get_page(page_number)
+
+ filters = request.GET.copy()
+ filters.pop("page", None)
+ current_filters_qs = filters.urlencode()
recent_jobs = (
JobPosting.objects.select_related("source")
@@ -166,8 +184,8 @@ def ops_dashboard(request):
.annotate(total=Count("id"))
.order_by("status")
)
- needs_attention = sources.filter(status=JobSource.Status.ERROR).count()
- stale_sources = sources.filter(last_checked_at__isnull=True).count()
+ needs_attention = sources_qs.filter(status=JobSource.Status.ERROR).count()
+ stale_sources = sources_qs.filter(last_checked_at__isnull=True).count()
return render(
request,
"core/ops_dashboard.html",
@@ -183,11 +201,12 @@ def ops_dashboard(request):
"needs_attention": needs_attention,
"stale_sources": stale_sources,
"active_jobs": JobPosting.objects.filter(is_active=True).count(),
- "total_sources": sources.count(),
+ "total_sources": sources_qs.count(),
"query": query,
"family": family,
"status": status,
"family_choices": JobSource.Family.choices,
"status_choices": JobSource.Status.choices,
+ "current_filters_qs": current_filters_qs,
},
)