We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Submission search
Search submissions akin to how users are searched

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `CTFd/admin/submissions.py`
Content:
```
1 from flask import render_template, request
2 
3 from CTFd.admin import admin
4 from CTFd.models import Challenges, Submissions
5 from CTFd.utils.decorators import admins_only
6 from CTFd.utils.modes import get_model
7 
8 
9 @admin.route("/admin/submissions", defaults={"submission_type": None})
10 @admin.route("/admin/submissions/<submission_type>")
11 @admins_only
12 def submissions_listing(submission_type):
13     filters = {}
14     if submission_type:
15         filters["type"] = submission_type
16 
17     curr_page = abs(int(request.args.get("page", 1, type=int)))
18     results_per_page = 50
19     page_start = results_per_page * (curr_page - 1)
20     page_end = results_per_page * (curr_page - 1) + results_per_page
21     sub_count = Submissions.query.filter_by(**filters).count()
22     page_count = int(sub_count / results_per_page) + (sub_count % results_per_page > 0)
23 
24     Model = get_model()
25 
26     submissions = (
27         Submissions.query.add_columns(
28             Submissions.id,
29             Submissions.type,
30             Submissions.challenge_id,
31             Submissions.provided,
32             Submissions.account_id,
33             Submissions.date,
34             Challenges.name.label("challenge_name"),
35             Model.name.label("team_name"),
36         )
37         .filter_by(**filters)
38         .join(Challenges)
39         .join(Model)
40         .order_by(Submissions.date.desc())
41         .slice(page_start, page_end)
42         .all()
43     )
44 
45     return render_template(
46         "admin/submissions.html",
47         submissions=submissions,
48         page_count=page_count,
49         curr_page=curr_page,
50         type=submission_type,
51     )
52
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/CTFd/admin/submissions.py b/CTFd/admin/submissions.py
--- a/CTFd/admin/submissions.py
+++ b/CTFd/admin/submissions.py
@@ -1,4 +1,4 @@
-from flask import render_template, request
+from flask import render_template, request, url_for
 
 from CTFd.admin import admin
 from CTFd.models import Challenges, Submissions
@@ -10,16 +10,21 @@
 @admin.route("/admin/submissions/<submission_type>")
 @admins_only
 def submissions_listing(submission_type):
-    filters = {}
+    filters_by = {}
     if submission_type:
-        filters["type"] = submission_type
+        filters_by["type"] = submission_type
+    filters = []
 
-    curr_page = abs(int(request.args.get("page", 1, type=int)))
-    results_per_page = 50
-    page_start = results_per_page * (curr_page - 1)
-    page_end = results_per_page * (curr_page - 1) + results_per_page
-    sub_count = Submissions.query.filter_by(**filters).count()
-    page_count = int(sub_count / results_per_page) + (sub_count % results_per_page > 0)
+    q = request.args.get("q")
+    field = request.args.get("field")
+    page = abs(request.args.get("page", 1, type=int))
+
+    if q:
+        submissions = []
+        if Submissions.__mapper__.has_property(
+            field
+        ):  # The field exists as an exposed column
+            filters.append(getattr(Submissions, field).like("%{}%".format(q)))
 
     Model = get_model()
 
@@ -34,18 +39,27 @@
             Challenges.name.label("challenge_name"),
             Model.name.label("team_name"),
         )
-        .filter_by(**filters)
+        .filter_by(**filters_by)
+        .filter(*filters)
         .join(Challenges)
         .join(Model)
         .order_by(Submissions.date.desc())
-        .slice(page_start, page_end)
-        .all()
+        .paginate(page=page, per_page=50)
     )
 
+    args = dict(request.args)
+    args.pop("page", 1)
+
     return render_template(
         "admin/submissions.html",
         submissions=submissions,
-        page_count=page_count,
-        curr_page=curr_page,
+        prev_page=url_for(
+            request.endpoint, type=submission_type, page=submissions.prev_num, **args
+        ),
+        next_page=url_for(
+            request.endpoint, type=submission_type, page=submissions.next_num, **args
+        ),
         type=submission_type,
+        q=q,
+        field=field,
     )

{"golden_diff": "diff --git a/CTFd/admin/submissions.py b/CTFd/admin/submissions.py\n--- a/CTFd/admin/submissions.py\n+++ b/CTFd/admin/submissions.py\n@@ -1,4 +1,4 @@\n-from flask import render_template, request\n+from flask import render_template, request, url_for\n \n from CTFd.admin import admin\n from CTFd.models import Challenges, Submissions\n@@ -10,16 +10,21 @@\n @admin.route(\"/admin/submissions/<submission_type>\")\n @admins_only\n def submissions_listing(submission_type):\n-    filters = {}\n+    filters_by = {}\n     if submission_type:\n-        filters[\"type\"] = submission_type\n+        filters_by[\"type\"] = submission_type\n+    filters = []\n \n-    curr_page = abs(int(request.args.get(\"page\", 1, type=int)))\n-    results_per_page = 50\n-    page_start = results_per_page * (curr_page - 1)\n-    page_end = results_per_page * (curr_page - 1) + results_per_page\n-    sub_count = Submissions.query.filter_by(**filters).count()\n-    page_count = int(sub_count / results_per_page) + (sub_count % results_per_page > 0)\n+    q = request.args.get(\"q\")\n+    field = request.args.get(\"field\")\n+    page = abs(request.args.get(\"page\", 1, type=int))\n+\n+    if q:\n+        submissions = []\n+        if Submissions.__mapper__.has_property(\n+            field\n+        ):  # The field exists as an exposed column\n+            filters.append(getattr(Submissions, field).like(\"%{}%\".format(q)))\n \n     Model = get_model()\n \n@@ -34,18 +39,27 @@\n             Challenges.name.label(\"challenge_name\"),\n             Model.name.label(\"team_name\"),\n         )\n-        .filter_by(**filters)\n+        .filter_by(**filters_by)\n+        .filter(*filters)\n         .join(Challenges)\n         .join(Model)\n         .order_by(Submissions.date.desc())\n-        .slice(page_start, page_end)\n-        .all()\n+        .paginate(page=page, per_page=50)\n     )\n \n+    args = dict(request.args)\n+    args.pop(\"page\", 1)\n+\n     return render_template(\n         \"admin/submissions.html\",\n         submissions=submissions,\n-        page_count=page_count,\n-        curr_page=curr_page,\n+        prev_page=url_for(\n+            request.endpoint, type=submission_type, page=submissions.prev_num, **args\n+        ),\n+        next_page=url_for(\n+            request.endpoint, type=submission_type, page=submissions.next_num, **args\n+        ),\n         type=submission_type,\n+        q=q,\n+        field=field,\n     )\n", "issue": "Submission search\nSearch submissions akin to how users are searched\n", "before_files": [{"content": "from flask import render_template, request\n\nfrom CTFd.admin import admin\nfrom CTFd.models import Challenges, Submissions\nfrom CTFd.utils.decorators import admins_only\nfrom CTFd.utils.modes import get_model\n\n\n@admin.route(\"/admin/submissions\", defaults={\"submission_type\": None})\n@admin.route(\"/admin/submissions/<submission_type>\")\n@admins_only\ndef submissions_listing(submission_type):\n    filters = {}\n    if submission_type:\n        filters[\"type\"] = submission_type\n\n    curr_page = abs(int(request.args.get(\"page\", 1, type=int)))\n    results_per_page = 50\n    page_start = results_per_page * (curr_page - 1)\n    page_end = results_per_page * (curr_page - 1) + results_per_page\n    sub_count = Submissions.query.filter_by(**filters).count()\n    page_count = int(sub_count / results_per_page) + (sub_count % results_per_page > 0)\n\n    Model = get_model()\n\n    submissions = (\n        Submissions.query.add_columns(\n            Submissions.id,\n            Submissions.type,\n            Submissions.challenge_id,\n            Submissions.provided,\n            Submissions.account_id,\n            Submissions.date,\n            Challenges.name.label(\"challenge_name\"),\n            Model.name.label(\"team_name\"),\n        )\n        .filter_by(**filters)\n        .join(Challenges)\n        .join(Model)\n        .order_by(Submissions.date.desc())\n        .slice(page_start, page_end)\n        .all()\n    )\n\n    return render_template(\n        \"admin/submissions.html\",\n        submissions=submissions,\n        page_count=page_count,\n        curr_page=curr_page,\n        type=submission_type,\n    )\n", "path": "CTFd/admin/submissions.py"}], "after_files": [{"content": "from flask import render_template, request, url_for\n\nfrom CTFd.admin import admin\nfrom CTFd.models import Challenges, Submissions\nfrom CTFd.utils.decorators import admins_only\nfrom CTFd.utils.modes import get_model\n\n\n@admin.route(\"/admin/submissions\", defaults={\"submission_type\": None})\n@admin.route(\"/admin/submissions/<submission_type>\")\n@admins_only\ndef submissions_listing(submission_type):\n    filters_by = {}\n    if submission_type:\n        filters_by[\"type\"] = submission_type\n    filters = []\n\n    q = request.args.get(\"q\")\n    field = request.args.get(\"field\")\n    page = abs(request.args.get(\"page\", 1, type=int))\n\n    if q:\n        submissions = []\n        if Submissions.__mapper__.has_property(\n            field\n        ):  # The field exists as an exposed column\n            filters.append(getattr(Submissions, field).like(\"%{}%\".format(q)))\n\n    Model = get_model()\n\n    submissions = (\n        Submissions.query.add_columns(\n            Submissions.id,\n            Submissions.type,\n            Submissions.challenge_id,\n            Submissions.provided,\n            Submissions.account_id,\n            Submissions.date,\n            Challenges.name.label(\"challenge_name\"),\n            Model.name.label(\"team_name\"),\n        )\n        .filter_by(**filters_by)\n        .filter(*filters)\n        .join(Challenges)\n        .join(Model)\n        .order_by(Submissions.date.desc())\n        .paginate(page=page, per_page=50)\n    )\n\n    args = dict(request.args)\n    args.pop(\"page\", 1)\n\n    return render_template(\n        \"admin/submissions.html\",\n        submissions=submissions,\n        prev_page=url_for(\n            request.endpoint, type=submission_type, page=submissions.prev_num, **args\n        ),\n        next_page=url_for(\n            request.endpoint, type=submission_type, page=submissions.next_num, **args\n        ),\n        type=submission_type,\n        q=q,\n        field=field,\n    )\n", "path": "CTFd/admin/submissions.py"}]}