We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
When user directly accesses '/auth/login' when already logged in, it should redirect the user to the home page
If a user session is active, the url `/auth/login/` should redirect to the home page i.e. database page. Currently, it displays the login page.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mathesar/urls.py`
Content:
```
1 from django.urls import include, path, re_path
2 from rest_framework_nested import routers
3 
4 from mathesar import views
5 from mathesar.api.db import viewsets as db_viewsets
6 from mathesar.api.ui import viewsets as ui_viewsets
7 from mathesar.users.password_reset import MathesarPasswordResetConfirmView
8 
9 db_router = routers.DefaultRouter()
10 db_router.register(r'tables', db_viewsets.TableViewSet, basename='table')
11 db_router.register(r'queries', db_viewsets.QueryViewSet, basename='query')
12 db_router.register(r'links', db_viewsets.LinkViewSet, basename='links')
13 db_router.register(r'schemas', db_viewsets.SchemaViewSet, basename='schema')
14 db_router.register(r'databases', db_viewsets.DatabaseViewSet, basename='database')
15 db_router.register(r'data_files', db_viewsets.DataFileViewSet, basename='data-file')
16 
17 db_table_router = routers.NestedSimpleRouter(db_router, r'tables', lookup='table')
18 db_table_router.register(r'records', db_viewsets.RecordViewSet, basename='table-record')
19 db_table_router.register(r'settings', db_viewsets.TableSettingsViewSet, basename='table-setting')
20 db_table_router.register(r'columns', db_viewsets.ColumnViewSet, basename='table-column')
21 db_table_router.register(r'constraints', db_viewsets.ConstraintViewSet, basename='table-constraint')
22 
23 ui_router = routers.DefaultRouter()
24 ui_router.register(r'version', ui_viewsets.VersionViewSet, basename='version')
25 ui_router.register(r'databases', ui_viewsets.DatabaseViewSet, basename='database')
26 ui_router.register(r'users', ui_viewsets.UserViewSet, basename='user')
27 ui_router.register(r'database_roles', ui_viewsets.DatabaseRoleViewSet, basename='database_role')
28 ui_router.register(r'schema_roles', ui_viewsets.SchemaRoleViewSet, basename='schema_role')
29 
30 urlpatterns = [
31     path('api/db/v0/', include(db_router.urls)),
32     path('api/db/v0/', include(db_table_router.urls)),
33     path('api/ui/v0/', include(ui_router.urls)),
34     path('api/ui/v0/reflect/', views.reflect_all, name='reflect_all'),
35     path('auth/password_reset_confirm', MathesarPasswordResetConfirmView.as_view(), name='password_reset_confirm'),
36     path('auth/', include('django.contrib.auth.urls')),
37     path('', views.home, name='home'),
38     path('<db_name>/', views.schemas, name='schemas'),
39     re_path(
40         r'^(?P<db_name>\w+)/(?P<schema_id>\w+)/',
41         views.schema_home,
42         name='schema_home'
43     ),
44 ]
45
```

Path: `config/settings.py`
Content:
```
1 """
2 Django settings for config project.
3 
4 Generated by 'django-admin startproject' using Django 3.1.7.
5 
6 For more information on this file, see
7 https://docs.djangoproject.com/en/3.1/topics/settings/
8 
9 For the full list of settings and their values, see
10 https://docs.djangoproject.com/en/3.1/ref/settings/
11 """
12 
13 import os
14 from pathlib import Path
15 
16 from decouple import Csv, config as decouple_config
17 from dj_database_url import parse as db_url
18 
19 
20 # We use a 'tuple' with pipes as delimiters as decople naively splits the global
21 # variables on commas when casting to Csv()
22 def pipe_delim(pipe_string):
23     # Remove opening and closing brackets
24     pipe_string = pipe_string[1:-1]
25     # Split on pipe delim
26     return pipe_string.split("|")
27 
28 
29 # Build paths inside the project like this: BASE_DIR / 'subdir'.
30 BASE_DIR = Path(__file__).resolve().parent.parent
31 
32 # Application definition
33 
34 INSTALLED_APPS = [
35     "django.contrib.admin",
36     "django.contrib.auth",
37     "django.contrib.contenttypes",
38     "django.contrib.sessions",
39     "django.contrib.messages",
40     "django.contrib.staticfiles",
41     "rest_framework",
42     "django_filters",
43     "django_property_filter",
44     "mathesar",
45 ]
46 
47 MIDDLEWARE = [
48     "django.middleware.security.SecurityMiddleware",
49     "django.contrib.sessions.middleware.SessionMiddleware",
50     "django.middleware.common.CommonMiddleware",
51     "django.middleware.csrf.CsrfViewMiddleware",
52     "django.contrib.auth.middleware.AuthenticationMiddleware",
53     "django.contrib.messages.middleware.MessageMiddleware",
54     "django.middleware.clickjacking.XFrameOptionsMiddleware",
55     "mathesar.middleware.CursorClosedHandlerMiddleware",
56     "mathesar.middleware.PasswordChangeNeededMiddleware",
57     'django_userforeignkey.middleware.UserForeignKeyMiddleware',
58     'django_request_cache.middleware.RequestCacheMiddleware',
59 ]
60 
61 ROOT_URLCONF = "config.urls"
62 
63 TEMPLATES = [
64     {
65         "BACKEND": "django.template.backends.django.DjangoTemplates",
66         "DIRS": [],
67         "APP_DIRS": True,
68         "OPTIONS": {
69             "context_processors": [
70                 "config.context_processors.frontend_settings",
71                 "django.template.context_processors.debug",
72                 "django.template.context_processors.request",
73                 "django.contrib.auth.context_processors.auth",
74                 "django.contrib.messages.context_processors.messages",
75             ],
76         },
77     },
78 ]
79 
80 WSGI_APPLICATION = "config.wsgi.application"
81 
82 # Database
83 # https://docs.djangoproject.com/en/3.1/ref/settings/#databases
84 
85 # TODO: Add to documentation that database keys should not be than 128 characters.
86 
87 # MATHESAR_DATABASES should be of the form '({db_name}|{db_url}), ({db_name}|{db_url})'
88 # See pipe_delim above for why we use pipes as delimiters
89 DATABASES = {
90     db_key: db_url(url_string)
91     for db_key, url_string in decouple_config('MATHESAR_DATABASES', cast=Csv(pipe_delim))
92 }
93 DATABASES[decouple_config('DJANGO_DATABASE_KEY')] = decouple_config('DJANGO_DATABASE_URL', cast=db_url)
94 
95 for db_key, db_dict in DATABASES.items():
96     # Engine can be '.postgresql' or '.postgresql_psycopg2'
97     if not db_dict['ENGINE'].startswith('django.db.backends.postgresql'):
98         raise ValueError(
99             f"{db_key} is not a PostgreSQL database. "
100             f"{db_dict['ENGINE']} found for {db_key}'s engine."
101         )
102 
103 
104 # pytest-django will create a new database named 'test_{DATABASES[table_db]['NAME']}'
105 # and use it for our API tests if we don't specify DATABASES[table_db]['TEST']['NAME']
106 TEST = decouple_config('TEST', default=False, cast=bool)
107 if TEST:
108     for db_key, _ in decouple_config('MATHESAR_DATABASES', cast=Csv(pipe_delim)):
109         DATABASES[db_key]['TEST'] = {'NAME': DATABASES[db_key]['NAME']}
110 
111 
112 # Quick-start development settings - unsuitable for production
113 # See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
114 
115 # SECURITY WARNING: keep the secret key used in production secret!
116 SECRET_KEY = decouple_config('SECRET_KEY')
117 
118 # SECURITY WARNING: don't run with debug turned on in production!
119 DEBUG = decouple_config('DEBUG', default=False, cast=bool)
120 
121 ALLOWED_HOSTS = decouple_config('ALLOWED_HOSTS', cast=Csv())
122 
123 # Password validation
124 # https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
125 
126 AUTH_PASSWORD_VALIDATORS = [
127     {
128         "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
129     },
130     {
131         "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
132     },
133     {
134         "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
135     },
136     {
137         "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
138     },
139 ]
140 
141 
142 # Internationalization
143 # https://docs.djangoproject.com/en/3.1/topics/i18n/
144 
145 LANGUAGE_CODE = "en-us"
146 
147 TIME_ZONE = "UTC"
148 
149 USE_I18N = True
150 
151 USE_L10N = True
152 
153 USE_TZ = True
154 
155 
156 # Static files (CSS, JavaScript, Images)
157 # https://docs.djangoproject.com/en/3.1/howto/static-files/
158 # https://docs.djangoproject.com/en/3.1/ref/contrib/staticfiles/
159 
160 STATIC_URL = "/static/"
161 
162 # When running with DEBUG=False, the webserver needs to serve files from this location
163 # python manage.py collectstatic has to be run to collect all static files into this location
164 # The files need to served in brotli or gzip compressed format
165 STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
166 
167 # Media files (uploaded by the user)
168 
169 MEDIA_ROOT = os.path.join(BASE_DIR, '.media/')
170 
171 MEDIA_URL = "/media/"
172 
173 # Update Authentication classes, removed BasicAuthentication
174 # Defaults: https://www.django-rest-framework.org/api-guide/settings/
175 REST_FRAMEWORK = {
176     'DEFAULT_AUTHENTICATION_CLASSES': [
177         'rest_framework.authentication.SessionAuthentication'
178     ],
179     'DEFAULT_PERMISSION_CLASSES': [
180         'rest_framework.permissions.IsAuthenticated',
181     ],
182     'DEFAULT_FILTER_BACKENDS': (
183         'django_filters.rest_framework.DjangoFilterBackend',
184         'rest_framework.filters.OrderingFilter',
185     ),
186     'TEST_REQUEST_DEFAULT_FORMAT': 'json',
187     'EXCEPTION_HANDLER':
188         'mathesar.exception_handlers.mathesar_exception_handler'
189 }
190 FRIENDLY_ERRORS = {
191     'FIELD_ERRORS': {
192         # By default drf-friendly-errors does contain error codes for ListSerializer type
193         'ListSerializer': {
194             'required': 2007,
195             'null': 2027,
196             'invalid_choice': 2083,
197             'not_a_list': 2123,
198             'empty': 2093
199         },
200         'PermittedPkRelatedField': {
201             'required': 2007,
202             'null': 2027,
203             'does_not_exist': 2151,
204             'incorrect_type': 2161
205         },
206         'PermittedSlugRelatedField': {
207             'required': 2007, 'invalid': 2002, 'null': 2027,
208             'does_not_exist': 2151, 'incorrect_type': 2161
209         },
210     },
211     'EXCEPTION_DICT': {
212         'Http404': 4005
213     }
214 }
215 # Mathesar settings
216 MATHESAR_MODE = decouple_config('MODE', default='PRODUCTION')
217 MATHESAR_UI_BUILD_LOCATION = os.path.join(BASE_DIR, 'mathesar/static/mathesar/')
218 MATHESAR_MANIFEST_LOCATION = os.path.join(MATHESAR_UI_BUILD_LOCATION, 'manifest.json')
219 MATHESAR_CLIENT_DEV_URL = 'http://localhost:3000'
220 MATHESAR_UI_SOURCE_LOCATION = os.path.join(BASE_DIR, 'mathesar_ui/')
221 MATHESAR_CAPTURE_UNHANDLED_EXCEPTION = decouple_config('CAPTURE_UNHANDLED_EXCEPTION', default=False)
222 MATHESAR_STATIC_NON_CODE_FILES_LOCATION = os.path.join(BASE_DIR, 'mathesar/static/non-code/')
223 
224 # UI source files have to be served by Django in order for static assets to be included during dev mode
225 # https://vitejs.dev/guide/assets.html
226 # https://vitejs.dev/guide/backend-integration.html
227 STATICFILES_DIRS = [MATHESAR_UI_SOURCE_LOCATION, MATHESAR_STATIC_NON_CODE_FILES_LOCATION] if MATHESAR_MODE == 'DEVELOPMENT' else [MATHESAR_UI_BUILD_LOCATION, MATHESAR_STATIC_NON_CODE_FILES_LOCATION]
228 
229 # Accounts
230 AUTH_USER_MODEL = 'mathesar.User'
231 LOGIN_URL = '/auth/login/'
232 LOGIN_REDIRECT_URL = '/'
233 LOGOUT_REDIRECT_URL = LOGIN_URL
234 DRF_ACCESS_POLICY = {
235     'reusable_conditions': ['mathesar.api.permission_conditions']
236 }
237
```
--- 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/config/settings.py b/config/settings.py
--- a/config/settings.py
+++ b/config/settings.py
@@ -100,7 +100,6 @@
             f"{db_dict['ENGINE']} found for {db_key}'s engine."
         )
 
-
 # pytest-django will create a new database named 'test_{DATABASES[table_db]['NAME']}'
 # and use it for our API tests if we don't specify DATABASES[table_db]['TEST']['NAME']
 TEST = decouple_config('TEST', default=False, cast=bool)
@@ -108,7 +107,6 @@
     for db_key, _ in decouple_config('MATHESAR_DATABASES', cast=Csv(pipe_delim)):
         DATABASES[db_key]['TEST'] = {'NAME': DATABASES[db_key]['NAME']}
 
-
 # Quick-start development settings - unsuitable for production
 # See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
 
@@ -138,7 +136,6 @@
     },
 ]
 
-
 # Internationalization
 # https://docs.djangoproject.com/en/3.1/topics/i18n/
 
@@ -152,7 +149,6 @@
 
 USE_TZ = True
 
-
 # Static files (CSS, JavaScript, Images)
 # https://docs.djangoproject.com/en/3.1/howto/static-files/
 # https://docs.djangoproject.com/en/3.1/ref/contrib/staticfiles/
diff --git a/mathesar/urls.py b/mathesar/urls.py
--- a/mathesar/urls.py
+++ b/mathesar/urls.py
@@ -1,3 +1,4 @@
+from django.contrib.auth.views import LoginView
 from django.urls import include, path, re_path
 from rest_framework_nested import routers
 
@@ -33,6 +34,7 @@
     path('api/ui/v0/', include(ui_router.urls)),
     path('api/ui/v0/reflect/', views.reflect_all, name='reflect_all'),
     path('auth/password_reset_confirm', MathesarPasswordResetConfirmView.as_view(), name='password_reset_confirm'),
+    path('auth/login/', LoginView.as_view(redirect_authenticated_user=True), name='login'),
     path('auth/', include('django.contrib.auth.urls')),
     path('', views.home, name='home'),
     path('<db_name>/', views.schemas, name='schemas'),

{"golden_diff": "diff --git a/config/settings.py b/config/settings.py\n--- a/config/settings.py\n+++ b/config/settings.py\n@@ -100,7 +100,6 @@\n             f\"{db_dict['ENGINE']} found for {db_key}'s engine.\"\n         )\n \n-\n # pytest-django will create a new database named 'test_{DATABASES[table_db]['NAME']}'\n # and use it for our API tests if we don't specify DATABASES[table_db]['TEST']['NAME']\n TEST = decouple_config('TEST', default=False, cast=bool)\n@@ -108,7 +107,6 @@\n     for db_key, _ in decouple_config('MATHESAR_DATABASES', cast=Csv(pipe_delim)):\n         DATABASES[db_key]['TEST'] = {'NAME': DATABASES[db_key]['NAME']}\n \n-\n # Quick-start development settings - unsuitable for production\n # See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/\n \n@@ -138,7 +136,6 @@\n     },\n ]\n \n-\n # Internationalization\n # https://docs.djangoproject.com/en/3.1/topics/i18n/\n \n@@ -152,7 +149,6 @@\n \n USE_TZ = True\n \n-\n # Static files (CSS, JavaScript, Images)\n # https://docs.djangoproject.com/en/3.1/howto/static-files/\n # https://docs.djangoproject.com/en/3.1/ref/contrib/staticfiles/\ndiff --git a/mathesar/urls.py b/mathesar/urls.py\n--- a/mathesar/urls.py\n+++ b/mathesar/urls.py\n@@ -1,3 +1,4 @@\n+from django.contrib.auth.views import LoginView\n from django.urls import include, path, re_path\n from rest_framework_nested import routers\n \n@@ -33,6 +34,7 @@\n     path('api/ui/v0/', include(ui_router.urls)),\n     path('api/ui/v0/reflect/', views.reflect_all, name='reflect_all'),\n     path('auth/password_reset_confirm', MathesarPasswordResetConfirmView.as_view(), name='password_reset_confirm'),\n+    path('auth/login/', LoginView.as_view(redirect_authenticated_user=True), name='login'),\n     path('auth/', include('django.contrib.auth.urls')),\n     path('', views.home, name='home'),\n     path('<db_name>/', views.schemas, name='schemas'),\n", "issue": "When user directly accesses '/auth/login' when already logged in, it should redirect the user to the home page\nIf a user session is active, the url `/auth/login/` should redirect to the home page i.e. database page. Currently, it displays the login page.\n", "before_files": [{"content": "from django.urls import include, path, re_path\nfrom rest_framework_nested import routers\n\nfrom mathesar import views\nfrom mathesar.api.db import viewsets as db_viewsets\nfrom mathesar.api.ui import viewsets as ui_viewsets\nfrom mathesar.users.password_reset import MathesarPasswordResetConfirmView\n\ndb_router = routers.DefaultRouter()\ndb_router.register(r'tables', db_viewsets.TableViewSet, basename='table')\ndb_router.register(r'queries', db_viewsets.QueryViewSet, basename='query')\ndb_router.register(r'links', db_viewsets.LinkViewSet, basename='links')\ndb_router.register(r'schemas', db_viewsets.SchemaViewSet, basename='schema')\ndb_router.register(r'databases', db_viewsets.DatabaseViewSet, basename='database')\ndb_router.register(r'data_files', db_viewsets.DataFileViewSet, basename='data-file')\n\ndb_table_router = routers.NestedSimpleRouter(db_router, r'tables', lookup='table')\ndb_table_router.register(r'records', db_viewsets.RecordViewSet, basename='table-record')\ndb_table_router.register(r'settings', db_viewsets.TableSettingsViewSet, basename='table-setting')\ndb_table_router.register(r'columns', db_viewsets.ColumnViewSet, basename='table-column')\ndb_table_router.register(r'constraints', db_viewsets.ConstraintViewSet, basename='table-constraint')\n\nui_router = routers.DefaultRouter()\nui_router.register(r'version', ui_viewsets.VersionViewSet, basename='version')\nui_router.register(r'databases', ui_viewsets.DatabaseViewSet, basename='database')\nui_router.register(r'users', ui_viewsets.UserViewSet, basename='user')\nui_router.register(r'database_roles', ui_viewsets.DatabaseRoleViewSet, basename='database_role')\nui_router.register(r'schema_roles', ui_viewsets.SchemaRoleViewSet, basename='schema_role')\n\nurlpatterns = [\n    path('api/db/v0/', include(db_router.urls)),\n    path('api/db/v0/', include(db_table_router.urls)),\n    path('api/ui/v0/', include(ui_router.urls)),\n    path('api/ui/v0/reflect/', views.reflect_all, name='reflect_all'),\n    path('auth/password_reset_confirm', MathesarPasswordResetConfirmView.as_view(), name='password_reset_confirm'),\n    path('auth/', include('django.contrib.auth.urls')),\n    path('', views.home, name='home'),\n    path('<db_name>/', views.schemas, name='schemas'),\n    re_path(\n        r'^(?P<db_name>\\w+)/(?P<schema_id>\\w+)/',\n        views.schema_home,\n        name='schema_home'\n    ),\n]\n", "path": "mathesar/urls.py"}, {"content": "\"\"\"\nDjango settings for config project.\n\nGenerated by 'django-admin startproject' using Django 3.1.7.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/3.1/topics/settings/\n\nFor the full list of settings and their values, see\nhttps://docs.djangoproject.com/en/3.1/ref/settings/\n\"\"\"\n\nimport os\nfrom pathlib import Path\n\nfrom decouple import Csv, config as decouple_config\nfrom dj_database_url import parse as db_url\n\n\n# We use a 'tuple' with pipes as delimiters as decople naively splits the global\n# variables on commas when casting to Csv()\ndef pipe_delim(pipe_string):\n    # Remove opening and closing brackets\n    pipe_string = pipe_string[1:-1]\n    # Split on pipe delim\n    return pipe_string.split(\"|\")\n\n\n# Build paths inside the project like this: BASE_DIR / 'subdir'.\nBASE_DIR = Path(__file__).resolve().parent.parent\n\n# Application definition\n\nINSTALLED_APPS = [\n    \"django.contrib.admin\",\n    \"django.contrib.auth\",\n    \"django.contrib.contenttypes\",\n    \"django.contrib.sessions\",\n    \"django.contrib.messages\",\n    \"django.contrib.staticfiles\",\n    \"rest_framework\",\n    \"django_filters\",\n    \"django_property_filter\",\n    \"mathesar\",\n]\n\nMIDDLEWARE = [\n    \"django.middleware.security.SecurityMiddleware\",\n    \"django.contrib.sessions.middleware.SessionMiddleware\",\n    \"django.middleware.common.CommonMiddleware\",\n    \"django.middleware.csrf.CsrfViewMiddleware\",\n    \"django.contrib.auth.middleware.AuthenticationMiddleware\",\n    \"django.contrib.messages.middleware.MessageMiddleware\",\n    \"django.middleware.clickjacking.XFrameOptionsMiddleware\",\n    \"mathesar.middleware.CursorClosedHandlerMiddleware\",\n    \"mathesar.middleware.PasswordChangeNeededMiddleware\",\n    'django_userforeignkey.middleware.UserForeignKeyMiddleware',\n    'django_request_cache.middleware.RequestCacheMiddleware',\n]\n\nROOT_URLCONF = \"config.urls\"\n\nTEMPLATES = [\n    {\n        \"BACKEND\": \"django.template.backends.django.DjangoTemplates\",\n        \"DIRS\": [],\n        \"APP_DIRS\": True,\n        \"OPTIONS\": {\n            \"context_processors\": [\n                \"config.context_processors.frontend_settings\",\n                \"django.template.context_processors.debug\",\n                \"django.template.context_processors.request\",\n                \"django.contrib.auth.context_processors.auth\",\n                \"django.contrib.messages.context_processors.messages\",\n            ],\n        },\n    },\n]\n\nWSGI_APPLICATION = \"config.wsgi.application\"\n\n# Database\n# https://docs.djangoproject.com/en/3.1/ref/settings/#databases\n\n# TODO: Add to documentation that database keys should not be than 128 characters.\n\n# MATHESAR_DATABASES should be of the form '({db_name}|{db_url}), ({db_name}|{db_url})'\n# See pipe_delim above for why we use pipes as delimiters\nDATABASES = {\n    db_key: db_url(url_string)\n    for db_key, url_string in decouple_config('MATHESAR_DATABASES', cast=Csv(pipe_delim))\n}\nDATABASES[decouple_config('DJANGO_DATABASE_KEY')] = decouple_config('DJANGO_DATABASE_URL', cast=db_url)\n\nfor db_key, db_dict in DATABASES.items():\n    # Engine can be '.postgresql' or '.postgresql_psycopg2'\n    if not db_dict['ENGINE'].startswith('django.db.backends.postgresql'):\n        raise ValueError(\n            f\"{db_key} is not a PostgreSQL database. \"\n            f\"{db_dict['ENGINE']} found for {db_key}'s engine.\"\n        )\n\n\n# pytest-django will create a new database named 'test_{DATABASES[table_db]['NAME']}'\n# and use it for our API tests if we don't specify DATABASES[table_db]['TEST']['NAME']\nTEST = decouple_config('TEST', default=False, cast=bool)\nif TEST:\n    for db_key, _ in decouple_config('MATHESAR_DATABASES', cast=Csv(pipe_delim)):\n        DATABASES[db_key]['TEST'] = {'NAME': DATABASES[db_key]['NAME']}\n\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = decouple_config('SECRET_KEY')\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = decouple_config('DEBUG', default=False, cast=bool)\n\nALLOWED_HOSTS = decouple_config('ALLOWED_HOSTS', cast=Csv())\n\n# Password validation\n# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.UserAttributeSimilarityValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.MinimumLengthValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.CommonPasswordValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.NumericPasswordValidator\",\n    },\n]\n\n\n# Internationalization\n# https://docs.djangoproject.com/en/3.1/topics/i18n/\n\nLANGUAGE_CODE = \"en-us\"\n\nTIME_ZONE = \"UTC\"\n\nUSE_I18N = True\n\nUSE_L10N = True\n\nUSE_TZ = True\n\n\n# Static files (CSS, JavaScript, Images)\n# https://docs.djangoproject.com/en/3.1/howto/static-files/\n# https://docs.djangoproject.com/en/3.1/ref/contrib/staticfiles/\n\nSTATIC_URL = \"/static/\"\n\n# When running with DEBUG=False, the webserver needs to serve files from this location\n# python manage.py collectstatic has to be run to collect all static files into this location\n# The files need to served in brotli or gzip compressed format\nSTATIC_ROOT = os.path.join(BASE_DIR, 'static/')\n\n# Media files (uploaded by the user)\n\nMEDIA_ROOT = os.path.join(BASE_DIR, '.media/')\n\nMEDIA_URL = \"/media/\"\n\n# Update Authentication classes, removed BasicAuthentication\n# Defaults: https://www.django-rest-framework.org/api-guide/settings/\nREST_FRAMEWORK = {\n    'DEFAULT_AUTHENTICATION_CLASSES': [\n        'rest_framework.authentication.SessionAuthentication'\n    ],\n    'DEFAULT_PERMISSION_CLASSES': [\n        'rest_framework.permissions.IsAuthenticated',\n    ],\n    'DEFAULT_FILTER_BACKENDS': (\n        'django_filters.rest_framework.DjangoFilterBackend',\n        'rest_framework.filters.OrderingFilter',\n    ),\n    'TEST_REQUEST_DEFAULT_FORMAT': 'json',\n    'EXCEPTION_HANDLER':\n        'mathesar.exception_handlers.mathesar_exception_handler'\n}\nFRIENDLY_ERRORS = {\n    'FIELD_ERRORS': {\n        # By default drf-friendly-errors does contain error codes for ListSerializer type\n        'ListSerializer': {\n            'required': 2007,\n            'null': 2027,\n            'invalid_choice': 2083,\n            'not_a_list': 2123,\n            'empty': 2093\n        },\n        'PermittedPkRelatedField': {\n            'required': 2007,\n            'null': 2027,\n            'does_not_exist': 2151,\n            'incorrect_type': 2161\n        },\n        'PermittedSlugRelatedField': {\n            'required': 2007, 'invalid': 2002, 'null': 2027,\n            'does_not_exist': 2151, 'incorrect_type': 2161\n        },\n    },\n    'EXCEPTION_DICT': {\n        'Http404': 4005\n    }\n}\n# Mathesar settings\nMATHESAR_MODE = decouple_config('MODE', default='PRODUCTION')\nMATHESAR_UI_BUILD_LOCATION = os.path.join(BASE_DIR, 'mathesar/static/mathesar/')\nMATHESAR_MANIFEST_LOCATION = os.path.join(MATHESAR_UI_BUILD_LOCATION, 'manifest.json')\nMATHESAR_CLIENT_DEV_URL = 'http://localhost:3000'\nMATHESAR_UI_SOURCE_LOCATION = os.path.join(BASE_DIR, 'mathesar_ui/')\nMATHESAR_CAPTURE_UNHANDLED_EXCEPTION = decouple_config('CAPTURE_UNHANDLED_EXCEPTION', default=False)\nMATHESAR_STATIC_NON_CODE_FILES_LOCATION = os.path.join(BASE_DIR, 'mathesar/static/non-code/')\n\n# UI source files have to be served by Django in order for static assets to be included during dev mode\n# https://vitejs.dev/guide/assets.html\n# https://vitejs.dev/guide/backend-integration.html\nSTATICFILES_DIRS = [MATHESAR_UI_SOURCE_LOCATION, MATHESAR_STATIC_NON_CODE_FILES_LOCATION] if MATHESAR_MODE == 'DEVELOPMENT' else [MATHESAR_UI_BUILD_LOCATION, MATHESAR_STATIC_NON_CODE_FILES_LOCATION]\n\n# Accounts\nAUTH_USER_MODEL = 'mathesar.User'\nLOGIN_URL = '/auth/login/'\nLOGIN_REDIRECT_URL = '/'\nLOGOUT_REDIRECT_URL = LOGIN_URL\nDRF_ACCESS_POLICY = {\n    'reusable_conditions': ['mathesar.api.permission_conditions']\n}\n", "path": "config/settings.py"}], "after_files": [{"content": "from django.contrib.auth.views import LoginView\nfrom django.urls import include, path, re_path\nfrom rest_framework_nested import routers\n\nfrom mathesar import views\nfrom mathesar.api.db import viewsets as db_viewsets\nfrom mathesar.api.ui import viewsets as ui_viewsets\nfrom mathesar.users.password_reset import MathesarPasswordResetConfirmView\n\ndb_router = routers.DefaultRouter()\ndb_router.register(r'tables', db_viewsets.TableViewSet, basename='table')\ndb_router.register(r'queries', db_viewsets.QueryViewSet, basename='query')\ndb_router.register(r'links', db_viewsets.LinkViewSet, basename='links')\ndb_router.register(r'schemas', db_viewsets.SchemaViewSet, basename='schema')\ndb_router.register(r'databases', db_viewsets.DatabaseViewSet, basename='database')\ndb_router.register(r'data_files', db_viewsets.DataFileViewSet, basename='data-file')\n\ndb_table_router = routers.NestedSimpleRouter(db_router, r'tables', lookup='table')\ndb_table_router.register(r'records', db_viewsets.RecordViewSet, basename='table-record')\ndb_table_router.register(r'settings', db_viewsets.TableSettingsViewSet, basename='table-setting')\ndb_table_router.register(r'columns', db_viewsets.ColumnViewSet, basename='table-column')\ndb_table_router.register(r'constraints', db_viewsets.ConstraintViewSet, basename='table-constraint')\n\nui_router = routers.DefaultRouter()\nui_router.register(r'version', ui_viewsets.VersionViewSet, basename='version')\nui_router.register(r'databases', ui_viewsets.DatabaseViewSet, basename='database')\nui_router.register(r'users', ui_viewsets.UserViewSet, basename='user')\nui_router.register(r'database_roles', ui_viewsets.DatabaseRoleViewSet, basename='database_role')\nui_router.register(r'schema_roles', ui_viewsets.SchemaRoleViewSet, basename='schema_role')\n\nurlpatterns = [\n    path('api/db/v0/', include(db_router.urls)),\n    path('api/db/v0/', include(db_table_router.urls)),\n    path('api/ui/v0/', include(ui_router.urls)),\n    path('api/ui/v0/reflect/', views.reflect_all, name='reflect_all'),\n    path('auth/password_reset_confirm', MathesarPasswordResetConfirmView.as_view(), name='password_reset_confirm'),\n    path('auth/login/', LoginView.as_view(redirect_authenticated_user=True), name='login'),\n    path('auth/', include('django.contrib.auth.urls')),\n    path('', views.home, name='home'),\n    path('<db_name>/', views.schemas, name='schemas'),\n    re_path(\n        r'^(?P<db_name>\\w+)/(?P<schema_id>\\w+)/',\n        views.schema_home,\n        name='schema_home'\n    ),\n]\n", "path": "mathesar/urls.py"}, {"content": "\"\"\"\nDjango settings for config project.\n\nGenerated by 'django-admin startproject' using Django 3.1.7.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/3.1/topics/settings/\n\nFor the full list of settings and their values, see\nhttps://docs.djangoproject.com/en/3.1/ref/settings/\n\"\"\"\n\nimport os\nfrom pathlib import Path\n\nfrom decouple import Csv, config as decouple_config\nfrom dj_database_url import parse as db_url\n\n\n# We use a 'tuple' with pipes as delimiters as decople naively splits the global\n# variables on commas when casting to Csv()\ndef pipe_delim(pipe_string):\n    # Remove opening and closing brackets\n    pipe_string = pipe_string[1:-1]\n    # Split on pipe delim\n    return pipe_string.split(\"|\")\n\n\n# Build paths inside the project like this: BASE_DIR / 'subdir'.\nBASE_DIR = Path(__file__).resolve().parent.parent\n\n# Application definition\n\nINSTALLED_APPS = [\n    \"django.contrib.admin\",\n    \"django.contrib.auth\",\n    \"django.contrib.contenttypes\",\n    \"django.contrib.sessions\",\n    \"django.contrib.messages\",\n    \"django.contrib.staticfiles\",\n    \"rest_framework\",\n    \"django_filters\",\n    \"django_property_filter\",\n    \"mathesar\",\n]\n\nMIDDLEWARE = [\n    \"django.middleware.security.SecurityMiddleware\",\n    \"django.contrib.sessions.middleware.SessionMiddleware\",\n    \"django.middleware.common.CommonMiddleware\",\n    \"django.middleware.csrf.CsrfViewMiddleware\",\n    \"django.contrib.auth.middleware.AuthenticationMiddleware\",\n    \"django.contrib.messages.middleware.MessageMiddleware\",\n    \"django.middleware.clickjacking.XFrameOptionsMiddleware\",\n    \"mathesar.middleware.CursorClosedHandlerMiddleware\",\n    \"mathesar.middleware.PasswordChangeNeededMiddleware\",\n    'django_userforeignkey.middleware.UserForeignKeyMiddleware',\n    'django_request_cache.middleware.RequestCacheMiddleware',\n]\n\nROOT_URLCONF = \"config.urls\"\n\nTEMPLATES = [\n    {\n        \"BACKEND\": \"django.template.backends.django.DjangoTemplates\",\n        \"DIRS\": [],\n        \"APP_DIRS\": True,\n        \"OPTIONS\": {\n            \"context_processors\": [\n                \"config.context_processors.frontend_settings\",\n                \"django.template.context_processors.debug\",\n                \"django.template.context_processors.request\",\n                \"django.contrib.auth.context_processors.auth\",\n                \"django.contrib.messages.context_processors.messages\",\n            ],\n        },\n    },\n]\n\nWSGI_APPLICATION = \"config.wsgi.application\"\n\n# Database\n# https://docs.djangoproject.com/en/3.1/ref/settings/#databases\n\n# TODO: Add to documentation that database keys should not be than 128 characters.\n\n# MATHESAR_DATABASES should be of the form '({db_name}|{db_url}), ({db_name}|{db_url})'\n# See pipe_delim above for why we use pipes as delimiters\nDATABASES = {\n    db_key: db_url(url_string)\n    for db_key, url_string in decouple_config('MATHESAR_DATABASES', cast=Csv(pipe_delim))\n}\nDATABASES[decouple_config('DJANGO_DATABASE_KEY')] = decouple_config('DJANGO_DATABASE_URL', cast=db_url)\n\nfor db_key, db_dict in DATABASES.items():\n    # Engine can be '.postgresql' or '.postgresql_psycopg2'\n    if not db_dict['ENGINE'].startswith('django.db.backends.postgresql'):\n        raise ValueError(\n            f\"{db_key} is not a PostgreSQL database. \"\n            f\"{db_dict['ENGINE']} found for {db_key}'s engine.\"\n        )\n\n# pytest-django will create a new database named 'test_{DATABASES[table_db]['NAME']}'\n# and use it for our API tests if we don't specify DATABASES[table_db]['TEST']['NAME']\nTEST = decouple_config('TEST', default=False, cast=bool)\nif TEST:\n    for db_key, _ in decouple_config('MATHESAR_DATABASES', cast=Csv(pipe_delim)):\n        DATABASES[db_key]['TEST'] = {'NAME': DATABASES[db_key]['NAME']}\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = decouple_config('SECRET_KEY')\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = decouple_config('DEBUG', default=False, cast=bool)\n\nALLOWED_HOSTS = decouple_config('ALLOWED_HOSTS', cast=Csv())\n\n# Password validation\n# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.UserAttributeSimilarityValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.MinimumLengthValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.CommonPasswordValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.NumericPasswordValidator\",\n    },\n]\n\n# Internationalization\n# https://docs.djangoproject.com/en/3.1/topics/i18n/\n\nLANGUAGE_CODE = \"en-us\"\n\nTIME_ZONE = \"UTC\"\n\nUSE_I18N = True\n\nUSE_L10N = True\n\nUSE_TZ = True\n\n# Static files (CSS, JavaScript, Images)\n# https://docs.djangoproject.com/en/3.1/howto/static-files/\n# https://docs.djangoproject.com/en/3.1/ref/contrib/staticfiles/\n\nSTATIC_URL = \"/static/\"\n\n# When running with DEBUG=False, the webserver needs to serve files from this location\n# python manage.py collectstatic has to be run to collect all static files into this location\n# The files need to served in brotli or gzip compressed format\nSTATIC_ROOT = os.path.join(BASE_DIR, 'static/')\n\n# Media files (uploaded by the user)\n\nMEDIA_ROOT = os.path.join(BASE_DIR, '.media/')\n\nMEDIA_URL = \"/media/\"\n\n# Update Authentication classes, removed BasicAuthentication\n# Defaults: https://www.django-rest-framework.org/api-guide/settings/\nREST_FRAMEWORK = {\n    'DEFAULT_AUTHENTICATION_CLASSES': [\n        'rest_framework.authentication.SessionAuthentication'\n    ],\n    'DEFAULT_PERMISSION_CLASSES': [\n        'rest_framework.permissions.IsAuthenticated',\n    ],\n    'DEFAULT_FILTER_BACKENDS': (\n        'django_filters.rest_framework.DjangoFilterBackend',\n        'rest_framework.filters.OrderingFilter',\n    ),\n    'TEST_REQUEST_DEFAULT_FORMAT': 'json',\n    'EXCEPTION_HANDLER':\n        'mathesar.exception_handlers.mathesar_exception_handler'\n}\nFRIENDLY_ERRORS = {\n    'FIELD_ERRORS': {\n        # By default drf-friendly-errors does contain error codes for ListSerializer type\n        'ListSerializer': {\n            'required': 2007,\n            'null': 2027,\n            'invalid_choice': 2083,\n            'not_a_list': 2123,\n            'empty': 2093\n        },\n        'PermittedPkRelatedField': {\n            'required': 2007,\n            'null': 2027,\n            'does_not_exist': 2151,\n            'incorrect_type': 2161\n        },\n        'PermittedSlugRelatedField': {\n            'required': 2007, 'invalid': 2002, 'null': 2027,\n            'does_not_exist': 2151, 'incorrect_type': 2161\n        },\n    },\n    'EXCEPTION_DICT': {\n        'Http404': 4005\n    }\n}\n# Mathesar settings\nMATHESAR_MODE = decouple_config('MODE', default='PRODUCTION')\nMATHESAR_UI_BUILD_LOCATION = os.path.join(BASE_DIR, 'mathesar/static/mathesar/')\nMATHESAR_MANIFEST_LOCATION = os.path.join(MATHESAR_UI_BUILD_LOCATION, 'manifest.json')\nMATHESAR_CLIENT_DEV_URL = 'http://localhost:3000'\nMATHESAR_UI_SOURCE_LOCATION = os.path.join(BASE_DIR, 'mathesar_ui/')\nMATHESAR_CAPTURE_UNHANDLED_EXCEPTION = decouple_config('CAPTURE_UNHANDLED_EXCEPTION', default=False)\nMATHESAR_STATIC_NON_CODE_FILES_LOCATION = os.path.join(BASE_DIR, 'mathesar/static/non-code/')\n\n# UI source files have to be served by Django in order for static assets to be included during dev mode\n# https://vitejs.dev/guide/assets.html\n# https://vitejs.dev/guide/backend-integration.html\nSTATICFILES_DIRS = [MATHESAR_UI_SOURCE_LOCATION, MATHESAR_STATIC_NON_CODE_FILES_LOCATION] if MATHESAR_MODE == 'DEVELOPMENT' else [MATHESAR_UI_BUILD_LOCATION, MATHESAR_STATIC_NON_CODE_FILES_LOCATION]\n\n# Accounts\nAUTH_USER_MODEL = 'mathesar.User'\nLOGIN_URL = '/auth/login/'\nLOGIN_REDIRECT_URL = '/'\nLOGOUT_REDIRECT_URL = LOGIN_URL\nDRF_ACCESS_POLICY = {\n    'reusable_conditions': ['mathesar.api.permission_conditions']\n}\n", "path": "config/settings.py"}]}