We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
More filters for table list API
**Problem**
<!-- Please provide a clear and concise description of the problem that this feature request is designed to solve.-->
The table list API should allow filtering. For example, we might want to get the list of all tables in a schema to see if the table the user is trying to create already exists in that schema.

**Proposed solution**
<!-- A clear and concise description of your proposed solution or feature. -->
The table list endpoint should support filtering by:
- schema
- before/after: created, last updated
- whether the import was verified

**Additional context**
<!-- Add any other context or screenshots about the feature request here.-->
We should use `django-filter` since it integrates with DRF and makes setting up filters easy.

--- 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/models.py`
Content:
```
1 from django.contrib.auth.models import User
2 from django.core.cache import cache
3 from django.db import models
4 from django.utils.functional import cached_property
5 
6 from mathesar.database.base import create_mathesar_engine
7 from mathesar.utils import models as model_utils
8 from db import tables, records, schemas
9 
10 NAME_CACHE_INTERVAL = 60 * 5
11 
12 
13 class BaseModel(models.Model):
14     created_at = models.DateTimeField(auto_now_add=True)
15     updated_at = models.DateTimeField(auto_now=True)
16 
17     class Meta:
18         abstract = True
19 
20 
21 class DatabaseObject(BaseModel):
22     oid = models.IntegerField()
23 
24     class Meta:
25         abstract = True
26 
27     def __str__(self):
28         return f"{self.__class__.__name__}: {self.oid}"
29 
30 
31 class Schema(DatabaseObject):
32     database = models.CharField(max_length=128)
33 
34     @cached_property
35     def _sa_engine(self):
36         # We're caching this since the engine is used frequently.
37         return create_mathesar_engine(self.database)
38 
39     @cached_property
40     def name(self):
41         cache_key = f"{self.database}_schema_name_{self.oid}"
42         try:
43             schema_name = cache.get(cache_key)
44             if schema_name is None:
45                 schema_name = schemas.get_schema_name_from_oid(
46                     self.oid, self._sa_engine
47                 )
48                 cache.set(cache_key, schema_name, NAME_CACHE_INTERVAL)
49             return schema_name
50         # We catch this error, since it lets us decouple the cadence of
51         # overall DB reflection from the cadence of cache expiration for
52         # schema names.  Also, it makes it obvious when the DB layer has
53         # been altered, as opposed to other reasons for a 404 when
54         # requesting a schema.
55         except TypeError:
56             return 'MISSING'
57 
58 
59 class Table(DatabaseObject):
60     schema = models.ForeignKey('Schema', on_delete=models.CASCADE,
61                                related_name='tables')
62     import_verified = models.BooleanField(blank=True, null=True)
63 
64     @cached_property
65     def _sa_table(self):
66         try:
67             table = tables.reflect_table_from_oid(
68                 self.oid, self.schema._sa_engine,
69             )
70         # We catch this error, since it lets us decouple the cadence of
71         # overall DB reflection from the cadence of cache expiration for
72         # table names.  Also, it makes it obvious when the DB layer has
73         # been altered, as opposed to other reasons for a 404 when
74         # requesting a table.
75         except TypeError:
76             table = tables.create_empty_table("MISSING")
77         return table
78 
79     @cached_property
80     def name(self):
81         return self._sa_table.name
82 
83     @property
84     def sa_columns(self):
85         return self._sa_table.columns
86 
87     @property
88     def sa_column_names(self):
89         return self.sa_columns.keys()
90 
91     @property
92     def sa_num_records(self):
93         return tables.get_count(self._sa_table, self.schema._sa_engine)
94 
95     @property
96     def sa_all_records(self):
97         return records.get_records(self._sa_table, self.schema._sa_engine)
98 
99     def get_record(self, id_value):
100         return records.get_record(self._sa_table, self.schema._sa_engine, id_value)
101 
102     def get_records(self, limit=None, offset=None):
103         return records.get_records(self._sa_table, self.schema._sa_engine, limit, offset)
104 
105     def create_record_or_records(self, record_data):
106         return records.create_record_or_records(self._sa_table, self.schema._sa_engine, record_data)
107 
108     def update_record(self, id_value, record_data):
109         return records.update_record(self._sa_table, self.schema._sa_engine, id_value, record_data)
110 
111     def delete_record(self, id_value):
112         return records.delete_record(self._sa_table, self.schema._sa_engine, id_value)
113 
114 
115 class DataFile(BaseModel):
116     file = models.FileField(
117         upload_to=model_utils.user_directory_path,
118     )
119     user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)
120     table_imported_to = models.ForeignKey(Table, related_name="data_files", blank=True,
121                                           null=True, on_delete=models.SET_NULL)
122     delimiter = models.CharField(max_length=1, default=',', blank=True)
123     escapechar = models.CharField(max_length=1, blank=True)
124     quotechar = models.CharField(max_length=1, default='"', blank=True)
125
```

Path: `mathesar/filters.py`
Content:
```
1 from django_property_filter import (
2     PropertyFilterSet, PropertyBaseInFilter, PropertyCharFilter,
3 )
4 
5 from mathesar.models import Schema, Table
6 
7 
8 class CharInFilter(PropertyBaseInFilter, PropertyCharFilter):
9     pass
10 
11 
12 class SchemaFilter(PropertyFilterSet):
13     database = CharInFilter(field_name='database', lookup_expr='in')
14     name = CharInFilter(field_name='name', lookup_expr='in')
15 
16     class Meta:
17         model = Schema
18         fields = ['database', 'name']
19 
20 
21 class TableFilter(PropertyFilterSet):
22     name = CharInFilter(field_name='name', lookup_expr='in')
23 
24     class Meta:
25         model = Table
26         fields = ['name']
27
```
--- 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/mathesar/filters.py b/mathesar/filters.py
--- a/mathesar/filters.py
+++ b/mathesar/filters.py
@@ -1,5 +1,6 @@
 from django_property_filter import (
     PropertyFilterSet, PropertyBaseInFilter, PropertyCharFilter,
+    PropertyDateTimeFromToRangeFilter, PropertyBooleanFilter
 )
 
 from mathesar.models import Schema, Table
@@ -20,7 +21,13 @@
 
 class TableFilter(PropertyFilterSet):
     name = CharInFilter(field_name='name', lookup_expr='in')
+    schema = CharInFilter(field_name='schema__name', lookup_expr='in')
+    created = PropertyDateTimeFromToRangeFilter(field_name='created_at')
+    updated = PropertyDateTimeFromToRangeFilter(field_name='updated_at')
+    import_verified = PropertyBooleanFilter(field_name='import_verified')
+    not_imported = PropertyBooleanFilter(lookup_expr="isnull",
+                                         field_name='import_verified')
 
     class Meta:
         model = Table
-        fields = ['name']
+        fields = ['name', 'schema', 'created_at', 'updated_at', 'import_verified']
diff --git a/mathesar/models.py b/mathesar/models.py
--- a/mathesar/models.py
+++ b/mathesar/models.py
@@ -28,13 +28,21 @@
         return f"{self.__class__.__name__}: {self.oid}"
 
 
+# TODO: Replace with a proper form of caching
+# See: https://github.com/centerofci/mathesar/issues/280
+_engine = None
+
+
 class Schema(DatabaseObject):
     database = models.CharField(max_length=128)
 
-    @cached_property
+    @property
     def _sa_engine(self):
+        global _engine
         # We're caching this since the engine is used frequently.
-        return create_mathesar_engine(self.database)
+        if _engine is None:
+            _engine = create_mathesar_engine(self.database)
+        return _engine
 
     @cached_property
     def name(self):

{"golden_diff": "diff --git a/mathesar/filters.py b/mathesar/filters.py\n--- a/mathesar/filters.py\n+++ b/mathesar/filters.py\n@@ -1,5 +1,6 @@\n from django_property_filter import (\n     PropertyFilterSet, PropertyBaseInFilter, PropertyCharFilter,\n+    PropertyDateTimeFromToRangeFilter, PropertyBooleanFilter\n )\n \n from mathesar.models import Schema, Table\n@@ -20,7 +21,13 @@\n \n class TableFilter(PropertyFilterSet):\n     name = CharInFilter(field_name='name', lookup_expr='in')\n+    schema = CharInFilter(field_name='schema__name', lookup_expr='in')\n+    created = PropertyDateTimeFromToRangeFilter(field_name='created_at')\n+    updated = PropertyDateTimeFromToRangeFilter(field_name='updated_at')\n+    import_verified = PropertyBooleanFilter(field_name='import_verified')\n+    not_imported = PropertyBooleanFilter(lookup_expr=\"isnull\",\n+                                         field_name='import_verified')\n \n     class Meta:\n         model = Table\n-        fields = ['name']\n+        fields = ['name', 'schema', 'created_at', 'updated_at', 'import_verified']\ndiff --git a/mathesar/models.py b/mathesar/models.py\n--- a/mathesar/models.py\n+++ b/mathesar/models.py\n@@ -28,13 +28,21 @@\n         return f\"{self.__class__.__name__}: {self.oid}\"\n \n \n+# TODO: Replace with a proper form of caching\n+# See: https://github.com/centerofci/mathesar/issues/280\n+_engine = None\n+\n+\n class Schema(DatabaseObject):\n     database = models.CharField(max_length=128)\n \n-    @cached_property\n+    @property\n     def _sa_engine(self):\n+        global _engine\n         # We're caching this since the engine is used frequently.\n-        return create_mathesar_engine(self.database)\n+        if _engine is None:\n+            _engine = create_mathesar_engine(self.database)\n+        return _engine\n \n     @cached_property\n     def name(self):\n", "issue": "More filters for table list API\n**Problem**\r\n<!-- Please provide a clear and concise description of the problem that this feature request is designed to solve.-->\r\nThe table list API should allow filtering. For example, we might want to get the list of all tables in a schema to see if the table the user is trying to create already exists in that schema.\r\n\r\n**Proposed solution**\r\n<!-- A clear and concise description of your proposed solution or feature. -->\r\nThe table list endpoint should support filtering by:\r\n- schema\r\n- before/after: created, last updated\r\n- whether the import was verified\r\n\r\n**Additional context**\r\n<!-- Add any other context or screenshots about the feature request here.-->\r\nWe should use `django-filter` since it integrates with DRF and makes setting up filters easy.\n", "before_files": [{"content": "from django.contrib.auth.models import User\nfrom django.core.cache import cache\nfrom django.db import models\nfrom django.utils.functional import cached_property\n\nfrom mathesar.database.base import create_mathesar_engine\nfrom mathesar.utils import models as model_utils\nfrom db import tables, records, schemas\n\nNAME_CACHE_INTERVAL = 60 * 5\n\n\nclass BaseModel(models.Model):\n    created_at = models.DateTimeField(auto_now_add=True)\n    updated_at = models.DateTimeField(auto_now=True)\n\n    class Meta:\n        abstract = True\n\n\nclass DatabaseObject(BaseModel):\n    oid = models.IntegerField()\n\n    class Meta:\n        abstract = True\n\n    def __str__(self):\n        return f\"{self.__class__.__name__}: {self.oid}\"\n\n\nclass Schema(DatabaseObject):\n    database = models.CharField(max_length=128)\n\n    @cached_property\n    def _sa_engine(self):\n        # We're caching this since the engine is used frequently.\n        return create_mathesar_engine(self.database)\n\n    @cached_property\n    def name(self):\n        cache_key = f\"{self.database}_schema_name_{self.oid}\"\n        try:\n            schema_name = cache.get(cache_key)\n            if schema_name is None:\n                schema_name = schemas.get_schema_name_from_oid(\n                    self.oid, self._sa_engine\n                )\n                cache.set(cache_key, schema_name, NAME_CACHE_INTERVAL)\n            return schema_name\n        # We catch this error, since it lets us decouple the cadence of\n        # overall DB reflection from the cadence of cache expiration for\n        # schema names.  Also, it makes it obvious when the DB layer has\n        # been altered, as opposed to other reasons for a 404 when\n        # requesting a schema.\n        except TypeError:\n            return 'MISSING'\n\n\nclass Table(DatabaseObject):\n    schema = models.ForeignKey('Schema', on_delete=models.CASCADE,\n                               related_name='tables')\n    import_verified = models.BooleanField(blank=True, null=True)\n\n    @cached_property\n    def _sa_table(self):\n        try:\n            table = tables.reflect_table_from_oid(\n                self.oid, self.schema._sa_engine,\n            )\n        # We catch this error, since it lets us decouple the cadence of\n        # overall DB reflection from the cadence of cache expiration for\n        # table names.  Also, it makes it obvious when the DB layer has\n        # been altered, as opposed to other reasons for a 404 when\n        # requesting a table.\n        except TypeError:\n            table = tables.create_empty_table(\"MISSING\")\n        return table\n\n    @cached_property\n    def name(self):\n        return self._sa_table.name\n\n    @property\n    def sa_columns(self):\n        return self._sa_table.columns\n\n    @property\n    def sa_column_names(self):\n        return self.sa_columns.keys()\n\n    @property\n    def sa_num_records(self):\n        return tables.get_count(self._sa_table, self.schema._sa_engine)\n\n    @property\n    def sa_all_records(self):\n        return records.get_records(self._sa_table, self.schema._sa_engine)\n\n    def get_record(self, id_value):\n        return records.get_record(self._sa_table, self.schema._sa_engine, id_value)\n\n    def get_records(self, limit=None, offset=None):\n        return records.get_records(self._sa_table, self.schema._sa_engine, limit, offset)\n\n    def create_record_or_records(self, record_data):\n        return records.create_record_or_records(self._sa_table, self.schema._sa_engine, record_data)\n\n    def update_record(self, id_value, record_data):\n        return records.update_record(self._sa_table, self.schema._sa_engine, id_value, record_data)\n\n    def delete_record(self, id_value):\n        return records.delete_record(self._sa_table, self.schema._sa_engine, id_value)\n\n\nclass DataFile(BaseModel):\n    file = models.FileField(\n        upload_to=model_utils.user_directory_path,\n    )\n    user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)\n    table_imported_to = models.ForeignKey(Table, related_name=\"data_files\", blank=True,\n                                          null=True, on_delete=models.SET_NULL)\n    delimiter = models.CharField(max_length=1, default=',', blank=True)\n    escapechar = models.CharField(max_length=1, blank=True)\n    quotechar = models.CharField(max_length=1, default='\"', blank=True)\n", "path": "mathesar/models.py"}, {"content": "from django_property_filter import (\n    PropertyFilterSet, PropertyBaseInFilter, PropertyCharFilter,\n)\n\nfrom mathesar.models import Schema, Table\n\n\nclass CharInFilter(PropertyBaseInFilter, PropertyCharFilter):\n    pass\n\n\nclass SchemaFilter(PropertyFilterSet):\n    database = CharInFilter(field_name='database', lookup_expr='in')\n    name = CharInFilter(field_name='name', lookup_expr='in')\n\n    class Meta:\n        model = Schema\n        fields = ['database', 'name']\n\n\nclass TableFilter(PropertyFilterSet):\n    name = CharInFilter(field_name='name', lookup_expr='in')\n\n    class Meta:\n        model = Table\n        fields = ['name']\n", "path": "mathesar/filters.py"}], "after_files": [{"content": "from django.contrib.auth.models import User\nfrom django.core.cache import cache\nfrom django.db import models\nfrom django.utils.functional import cached_property\n\nfrom mathesar.database.base import create_mathesar_engine\nfrom mathesar.utils import models as model_utils\nfrom db import tables, records, schemas\n\nNAME_CACHE_INTERVAL = 60 * 5\n\n\nclass BaseModel(models.Model):\n    created_at = models.DateTimeField(auto_now_add=True)\n    updated_at = models.DateTimeField(auto_now=True)\n\n    class Meta:\n        abstract = True\n\n\nclass DatabaseObject(BaseModel):\n    oid = models.IntegerField()\n\n    class Meta:\n        abstract = True\n\n    def __str__(self):\n        return f\"{self.__class__.__name__}: {self.oid}\"\n\n\n# TODO: Replace with a proper form of caching\n# See: https://github.com/centerofci/mathesar/issues/280\n_engine = None\n\n\nclass Schema(DatabaseObject):\n    database = models.CharField(max_length=128)\n\n    @property\n    def _sa_engine(self):\n        global _engine\n        # We're caching this since the engine is used frequently.\n        if _engine is None:\n            _engine = create_mathesar_engine(self.database)\n        return _engine\n\n    @cached_property\n    def name(self):\n        cache_key = f\"{self.database}_schema_name_{self.oid}\"\n        try:\n            schema_name = cache.get(cache_key)\n            if schema_name is None:\n                schema_name = schemas.get_schema_name_from_oid(\n                    self.oid, self._sa_engine\n                )\n                cache.set(cache_key, schema_name, NAME_CACHE_INTERVAL)\n            return schema_name\n        # We catch this error, since it lets us decouple the cadence of\n        # overall DB reflection from the cadence of cache expiration for\n        # schema names.  Also, it makes it obvious when the DB layer has\n        # been altered, as opposed to other reasons for a 404 when\n        # requesting a schema.\n        except TypeError:\n            return 'MISSING'\n\n\nclass Table(DatabaseObject):\n    schema = models.ForeignKey('Schema', on_delete=models.CASCADE,\n                               related_name='tables')\n    import_verified = models.BooleanField(blank=True, null=True)\n\n    @cached_property\n    def _sa_table(self):\n        try:\n            table = tables.reflect_table_from_oid(\n                self.oid, self.schema._sa_engine,\n            )\n        # We catch this error, since it lets us decouple the cadence of\n        # overall DB reflection from the cadence of cache expiration for\n        # table names.  Also, it makes it obvious when the DB layer has\n        # been altered, as opposed to other reasons for a 404 when\n        # requesting a table.\n        except TypeError:\n            table = tables.create_empty_table(\"MISSING\")\n        return table\n\n    @cached_property\n    def name(self):\n        return self._sa_table.name\n\n    @property\n    def sa_columns(self):\n        return self._sa_table.columns\n\n    @property\n    def sa_column_names(self):\n        return self.sa_columns.keys()\n\n    @property\n    def sa_num_records(self):\n        return tables.get_count(self._sa_table, self.schema._sa_engine)\n\n    @property\n    def sa_all_records(self):\n        return records.get_records(self._sa_table, self.schema._sa_engine)\n\n    def get_record(self, id_value):\n        return records.get_record(self._sa_table, self.schema._sa_engine, id_value)\n\n    def get_records(self, limit=None, offset=None):\n        return records.get_records(self._sa_table, self.schema._sa_engine, limit, offset)\n\n    def create_record_or_records(self, record_data):\n        return records.create_record_or_records(self._sa_table, self.schema._sa_engine, record_data)\n\n    def update_record(self, id_value, record_data):\n        return records.update_record(self._sa_table, self.schema._sa_engine, id_value, record_data)\n\n    def delete_record(self, id_value):\n        return records.delete_record(self._sa_table, self.schema._sa_engine, id_value)\n\n\nclass DataFile(BaseModel):\n    file = models.FileField(\n        upload_to=model_utils.user_directory_path,\n    )\n    user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)\n    table_imported_to = models.ForeignKey(Table, related_name=\"data_files\", blank=True,\n                                          null=True, on_delete=models.SET_NULL)\n    delimiter = models.CharField(max_length=1, default=',', blank=True)\n    escapechar = models.CharField(max_length=1, blank=True)\n    quotechar = models.CharField(max_length=1, default='\"', blank=True)\n", "path": "mathesar/models.py"}, {"content": "from django_property_filter import (\n    PropertyFilterSet, PropertyBaseInFilter, PropertyCharFilter,\n    PropertyDateTimeFromToRangeFilter, PropertyBooleanFilter\n)\n\nfrom mathesar.models import Schema, Table\n\n\nclass CharInFilter(PropertyBaseInFilter, PropertyCharFilter):\n    pass\n\n\nclass SchemaFilter(PropertyFilterSet):\n    database = CharInFilter(field_name='database', lookup_expr='in')\n    name = CharInFilter(field_name='name', lookup_expr='in')\n\n    class Meta:\n        model = Schema\n        fields = ['database', 'name']\n\n\nclass TableFilter(PropertyFilterSet):\n    name = CharInFilter(field_name='name', lookup_expr='in')\n    schema = CharInFilter(field_name='schema__name', lookup_expr='in')\n    created = PropertyDateTimeFromToRangeFilter(field_name='created_at')\n    updated = PropertyDateTimeFromToRangeFilter(field_name='updated_at')\n    import_verified = PropertyBooleanFilter(field_name='import_verified')\n    not_imported = PropertyBooleanFilter(lookup_expr=\"isnull\",\n                                         field_name='import_verified')\n\n    class Meta:\n        model = Table\n        fields = ['name', 'schema', 'created_at', 'updated_at', 'import_verified']\n", "path": "mathesar/filters.py"}]}