html_url,issue_url,id,node_id,user,user_label,created_at,updated_at,author_association,body,reactions,issue,issue_label,performed_via_github_app https://github.com/simonw/datasette/issues/617#issuecomment-552253893,https://api.github.com/repos/simonw/datasette/issues/617,552253893,MDEyOklzc3VlQ29tbWVudDU1MjI1Mzg5Mw==,9599,simonw,2019-11-11T00:46:42Z,2021-12-18T01:41:47Z,OWNER,"As noted in https://github.com/simonw/datasette/issues/621#issuecomment-552253208 a common pattern in this method is blocks of code that append new items to the `where_clauses`, `params` and `extra_human_descriptions` arrays. This is a useful refactoring opportunity. Code that fits this pattern: * The code that builds based on the filters: `where_clauses, params = filters.build_where_clauses(table)` and `human_description_en = filters.human_description_en(extra=extra_human_descriptions)` * Code that handles `?_where=`: `where_clauses.extend(request.args[""_where""])` - though note that this also appends to a `extra_wheres_for_ui` array which nothing else uses * The `_through=` code, see #621 for details * The code that deals with `?_search=` FTS The keyset pagination code modifies `where_clauses` and `params` too, but I don't think it's quite going to work with the same abstraction that would cover the above examples. [UPDATE December 2021 - this comment became the basis for a new `filters_from_request` plugin hook, see also #473]","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",519613116,Refactor TableView.data() method, https://github.com/simonw/datasette/pull/595#issuecomment-552327079,https://api.github.com/repos/simonw/datasette/issues/595,552327079,MDEyOklzc3VlQ29tbWVudDU1MjMyNzA3OQ==,647359,tomchristie,2019-11-11T07:34:27Z,2019-11-11T07:34:27Z,NONE,"> Glitch has been upgraded to Python 3.7. Whoop! 🥳 ✨ ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",506300941,bump uvicorn to 0.9.0 to be Python-3.8 friendly, https://github.com/simonw/datasette/pull/623#issuecomment-552281217,https://api.github.com/repos/simonw/datasette/issues/623,552281217,MDEyOklzc3VlQ29tbWVudDU1MjI4MTIxNw==,9599,simonw,2019-11-11T03:40:59Z,2019-11-11T03:40:59Z,OWNER,"That did the trick - still some warnings now but they are all in dependencies: ``` =============================== warnings summary =============================== /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/pint/compat/chainmap.py:16 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/pint/compat/chainmap.py:16: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.9 it will stop working from collections import MutableMapping /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/pint/util.py:21 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/pint/util.py:21: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.9 it will stop working from collections import Mapping /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:17 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:17: DeprecationWarning: ""@coroutine"" decorator is deprecated since Python 3.8, use ""async def"" instead def __anext__(self): /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:63 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:63: DeprecationWarning: ""@coroutine"" decorator is deprecated since Python 3.8, use ""async def"" instead def __iter__(self): /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:72 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:72: DeprecationWarning: ""@coroutine"" decorator is deprecated since Python 3.8, use ""async def"" instead def __anext__(self): /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:77 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:77: DeprecationWarning: ""@coroutine"" decorator is deprecated since Python 3.8, use ""async def"" instead def __aenter__(self): /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:82 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:82: DeprecationWarning: ""@coroutine"" decorator is deprecated since Python 3.8, use ""async def"" instead def __aexit__(self, exc_type, exc, tb): /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:91 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/base.py:91: DeprecationWarning: ""@coroutine"" decorator is deprecated since Python 3.8, use ""async def"" instead def __aexit__(self, exc_type, exc_val, exc_tb): /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/utils.py:33: DeprecationWarning: ""@coroutine"" decorator is deprecated since Python 3.8, use ""async def"" instead def method(self, *args, **kwargs): /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/__init__.py:27 /home/travis/virtualenv/python3.8.0/lib/python3.8/site-packages/aiofiles/threadpool/__init__.py:27: DeprecationWarning: ""@coroutine"" decorator is deprecated since Python 3.8, use ""async def"" instead def _open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, -- Docs: https://docs.pytest.org/en/latest/warnings.html ================== 379 passed, 54 warnings in 201.62 seconds =================== ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",520718056,Test against Python 3.8 in Travis, https://github.com/simonw/datasette/pull/623#issuecomment-552279522,https://api.github.com/repos/simonw/datasette/issues/623,552279522,MDEyOklzc3VlQ29tbWVudDU1MjI3OTUyMg==,9599,simonw,2019-11-11T03:31:17Z,2019-11-11T03:31:17Z,OWNER,"`================= 379 passed, 4332 warnings in 195.71 seconds ==================` I think all of those warnings are the same: ``` /home/travis/build/simonw/datasette/datasette/tracer.py:17: DeprecationWarning: Task.current_task() is deprecated, use asyncio.current_task() instead return id(asyncio.Task.current_task(loop=loop)) ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",520718056,Test against Python 3.8 in Travis, https://github.com/simonw/datasette/pull/501#issuecomment-552278216,https://api.github.com/repos/simonw/datasette/issues/501,552278216,MDEyOklzc3VlQ29tbWVudDU1MjI3ODIxNg==,9599,simonw,2019-11-11T03:23:29Z,2019-11-11T03:23:29Z,OWNER,Closing this so I can do a clean single commit instead.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",452901999,Test against Python 3.8-dev using Travis, https://github.com/simonw/datasette/pull/501#issuecomment-552278039,https://api.github.com/repos/simonw/datasette/issues/501,552278039,MDEyOklzc3VlQ29tbWVudDU1MjI3ODAzOQ==,9599,simonw,2019-11-11T03:22:36Z,2019-11-11T03:22:36Z,OWNER,"Wow! `= 379 passed, 4332 warnings in 196.92 seconds =` - that's a lot of warnings.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",452901999,Test against Python 3.8-dev using Travis, https://github.com/simonw/datasette/pull/501#issuecomment-552276422,https://api.github.com/repos/simonw/datasette/issues/501,552276422,MDEyOklzc3VlQ29tbWVudDU1MjI3NjQyMg==,9599,simonw,2019-11-11T03:13:52Z,2019-11-11T03:13:52Z,OWNER,Dropping 3.5 compatibility will help here #622 ,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",452901999,Test against Python 3.8-dev using Travis, https://github.com/simonw/datasette/pull/404#issuecomment-552276277,https://api.github.com/repos/simonw/datasette/issues/404,552276277,MDEyOklzc3VlQ29tbWVudDU1MjI3NjI3Nw==,9599,simonw,2019-11-11T03:13:09Z,2019-11-11T03:13:09Z,OWNER,#622 will drop 3.5 support.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",403499298,Experiment: run Jinja in async mode, https://github.com/simonw/datasette/issues/594#issuecomment-552276247,https://api.github.com/repos/simonw/datasette/issues/594,552276247,MDEyOklzc3VlQ29tbWVudDU1MjI3NjI0Nw==,9599,simonw,2019-11-11T03:13:00Z,2019-11-11T03:13:00Z,OWNER,#622,"{""total_count"": 1, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 1, ""rocket"": 0, ""eyes"": 0}",506297048,upgrade to uvicorn-0.9 to be Python-3.8 friendly, https://github.com/simonw/datasette/pull/595#issuecomment-552276237,https://api.github.com/repos/simonw/datasette/issues/595,552276237,MDEyOklzc3VlQ29tbWVudDU1MjI3NjIzNw==,9599,simonw,2019-11-11T03:12:56Z,2019-11-11T03:12:56Z,OWNER,#622,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",506300941,bump uvicorn to 0.9.0 to be Python-3.8 friendly, https://github.com/simonw/datasette/pull/595#issuecomment-552275668,https://api.github.com/repos/simonw/datasette/issues/595,552275668,MDEyOklzc3VlQ29tbWVudDU1MjI3NTY2OA==,9599,simonw,2019-11-11T03:09:43Z,2019-11-11T03:09:43Z,OWNER,Glitch has been upgraded to Python 3.7. I think I'm happy to drop 3.5 support now - users who want Python 3.5 can get it by installing `datasette==0.30.2`,"{""total_count"": 1, ""+1"": 1, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",506300941,bump uvicorn to 0.9.0 to be Python-3.8 friendly, https://github.com/simonw/datasette/pull/181#issuecomment-552275451,https://api.github.com/repos/simonw/datasette/issues/181,552275451,MDEyOklzc3VlQ29tbWVudDU1MjI3NTQ1MQ==,9599,simonw,2019-11-11T03:08:25Z,2019-11-11T03:08:25Z,OWNER,Closing this because this feature was shipped in #592 ,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",289425975,"add ""format sql"" button to query page, uses sql-formatter", https://github.com/simonw/datasette/issues/617#issuecomment-552254753,https://api.github.com/repos/simonw/datasette/issues/617,552254753,MDEyOklzc3VlQ29tbWVudDU1MjI1NDc1Mw==,9599,simonw,2019-11-11T00:54:51Z,2019-11-11T00:54:51Z,OWNER,"That `table_filter()` plugin hook should probably be renamed though, since it could now apply to the regular custom SQL view as well as the table view.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",519613116,Refactor TableView.data() method, https://github.com/simonw/datasette/issues/617#issuecomment-552254238,https://api.github.com/repos/simonw/datasette/issues/617,552254238,MDEyOklzc3VlQ29tbWVudDU1MjI1NDIzOA==,9599,simonw,2019-11-11T00:49:57Z,2019-11-11T00:51:35Z,OWNER,I experimented with a `table_filter()` plugin hook a while ago which looks very much like the abstraction I'm now talking about here: https://github.com/simonw/datasette/commit/5116c4ec8aed5091e1f75415424b80f613518dc6 - more details here: https://simonwillison.net/2018/Aug/6/russian-facebook-ads/#Weird_implementation_details_106,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",519613116,Refactor TableView.data() method, https://github.com/simonw/datasette/issues/621#issuecomment-552253208,https://api.github.com/repos/simonw/datasette/issues/621,552253208,MDEyOklzc3VlQ29tbWVudDU1MjI1MzIwOA==,9599,simonw,2019-11-11T00:39:57Z,2019-11-11T00:39:57Z,OWNER,"This is a nice opportunity to help with the refactoring of the table view in #617 - the above code snippet takes the request, looks at the `_through=` parameters and appends things to the `where_clauses`, `params` and `extra_human_descriptions` lists. I can factor that out into a separate private method on `TableView` and use that as a pattern for further refactoring.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",520681725,Syntax for ?_through= that works as a form field, https://github.com/simonw/datasette/issues/621#issuecomment-552251645,https://api.github.com/repos/simonw/datasette/issues/621,552251645,MDEyOklzc3VlQ29tbWVudDU1MjI1MTY0NQ==,9599,simonw,2019-11-11T00:23:56Z,2019-11-11T00:33:31Z,OWNER,"Current syntax: https://datasette.readthedocs.io/en/stable/json_api.html#special-table-arguments `/?_through={""table"":""roadside_attraction_characteristics"",""column"":""characteristic_id"",""value"":""1""}` Demo: https://latest.datasette.io/fixtures/roadside_attractions?_through={%22table%22:%22roadside_attraction_characteristics%22,%22column%22:%22characteristic_id%22,%22value%22:%221%22} The alternative syntax for that could be: `https://latest.datasette.io/fixtures/roadside_attractions?_through.roadside_attraction_characteristics.characteristic_id=1`","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",520681725,Syntax for ?_through= that works as a form field, https://github.com/simonw/datasette/issues/621#issuecomment-552251666,https://api.github.com/repos/simonw/datasette/issues/621,552251666,MDEyOklzc3VlQ29tbWVudDU1MjI1MTY2Ng==,9599,simonw,2019-11-11T00:24:09Z,2019-11-11T00:32:49Z,OWNER,"Here's the current code: https://github.com/simonw/datasette/blob/28c4a6db5b5e512db630d7ba6127196185de67c7/datasette/views/table.py#L316-L348","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",520681725,Syntax for ?_through= that works as a form field, https://github.com/simonw/datasette/issues/620#issuecomment-552252074,https://api.github.com/repos/simonw/datasette/issues/620,552252074,MDEyOklzc3VlQ29tbWVudDU1MjI1MjA3NA==,9599,simonw,2019-11-11T00:28:28Z,2019-11-11T00:30:53Z,OWNER,"So for foreign key definitions it could look like this: `/db/table?_fk.article_id=articles.id` Or for columns and table names that themselves contain dots it could be: `/db/table?_fk.article_id={""table"":""articles"",""column"":""id""}` The value (before the =) is unambiguous -it's `?fk.XXX` where XXX could be a column name that includes periods without breaking anything. Added bonus: if you're referencing another table's single primary key you can omit the `.id` entirely (since it can be automatically detected) - so you could do `?_fk.article_id=articles`.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",520667773,Mechanism for indicating foreign key relationships in the table and query page URLs, https://github.com/simonw/datasette/issues/620#issuecomment-552252199,https://api.github.com/repos/simonw/datasette/issues/620,552252199,MDEyOklzc3VlQ29tbWVudDU1MjI1MjE5OQ==,9599,simonw,2019-11-11T00:29:36Z,2019-11-11T00:29:36Z,OWNER,This new `?_fk.column_name=` syntax makes me wonder if the various filters should be `?colname.contains=x` rather than `?colname__contains=x` - but that's a conversation for another time.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",520667773,Mechanism for indicating foreign key relationships in the table and query page URLs, https://github.com/simonw/datasette/issues/620#issuecomment-552251831,https://api.github.com/repos/simonw/datasette/issues/620,552251831,MDEyOklzc3VlQ29tbWVudDU1MjI1MTgzMQ==,9599,simonw,2019-11-11T00:25:58Z,2019-11-11T00:25:58Z,OWNER,"There are three pieces of information that need to be described here: the column, the other table and the other table column. We already have a piece of API design that is similar to this: the `_through=` parameter, which looks like this: `?_through={""table"":""m2m_characteristics"",""column"":""characteristic_id"",""value"":""1""}` I'm rethinking this syntax in #621 though to support a non-JSON variant that looks more like this: `?_through.roadside_attraction_characteristics.characteristic_id=1`","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",520667773,Mechanism for indicating foreign key relationships in the table and query page URLs,