diff --git a/datasette/views/base.py b/datasette/views/base.py index a30eea18..f81617a0 100644 --- a/datasette/views/base.py +++ b/datasette/views/base.py @@ -208,7 +208,12 @@ class BaseView(RenderMixin): if "as_db" in kwargs: should_redirect += kwargs["as_db"] - if self.ds.config("hash_urls") or "_hash" in request.args: + if ( + (self.ds.config("hash_urls") or "_hash" in request.args) + and + # Redirect only if database is immutable + not self.ds.databases[name].is_mutable + ): return name, expected, correct_hash_provided, should_redirect return name, expected, correct_hash_provided, None diff --git a/tests/test_api.py b/tests/test_api.py index 693fe0a1..6fedc118 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1421,15 +1421,27 @@ def test_ttl_parameter(app_client, path, expected_cache_control): ), ], ) -def test_hash_parameter(app_client_with_hash, path, expected_redirect): +def test_hash_parameter( + app_client_two_attached_databases_one_immutable, path, expected_redirect +): # First get the current hash for the fixtures database - current_hash = app_client_with_hash.ds.databases["fixtures"].hash[:7] - response = app_client_with_hash.get(path, allow_redirects=False) + current_hash = app_client_two_attached_databases_one_immutable.ds.databases[ + "fixtures" + ].hash[:7] + response = app_client_two_attached_databases_one_immutable.get( + path, allow_redirects=False + ) assert response.status == 302 location = response.headers["Location"] assert expected_redirect.replace("HASH", current_hash) == location +def test_hash_parameter_ignored_for_mutable_databases(app_client): + path = "/fixtures/facetable.json?_hash=1" + response = app_client.get(path, allow_redirects=False) + assert response.status == 200 + + test_json_columns_default_expected = [ {"intval": 1, "strval": "s", "floatval": 0.5, "jsonval": '{"foo": "bar"}'} ]