Compare commits

...

3 commits

Author SHA1 Message Date
Simon Willison
af4ce463e7
Hacky way of adding to human description 2018-07-30 21:00:51 -07:00
Simon Willison
04c7fd6207
Handle multiple m2m args of same name
e.g. ?_m2m_ad_targets__target_id=ec3ac&_m2m_ad_targets__target_id=e128e
2018-07-30 20:54:38 -07:00
Simon Willison
0cf91e3f88
Started playing with m2m options
This query is really slow. I think this pattern would be faster:

	select ads.id, ads.text, ads.url
	from ads
	  inner join ad_targets ad_targets_1 on ad_targets_1.ad_id = ads.id
	  inner join ad_targets ad_targets_2 on ad_targets_2.ad_id = ads.id
	  where ad_targets_1.target_id = "cd0d0"
	  and ad_targets_2.target_id = "26eb3"
	order by ads.id
2018-07-30 08:16:56 -07:00

View file

@ -269,7 +269,7 @@ class TableView(RowTableShared):
special_args_lists = {} special_args_lists = {}
other_args = {} other_args = {}
for key, value in args.items(): for key, value in args.items():
if key.startswith("_") and "__" not in key: if (key.startswith("_") and "__" not in key) or key.startswith("_m2m_"):
special_args[key] = value[0] special_args[key] = value[0]
special_args_lists[key] = value special_args_lists[key] = value
else: else:
@ -304,6 +304,35 @@ class TableView(RowTableShared):
filters = Filters(sorted(other_args.items()), units, ureg) filters = Filters(sorted(other_args.items()), units, ureg)
where_clauses, params = filters.build_where_clauses() where_clauses, params = filters.build_where_clauses()
# Hacky thing for ?_m2m_ad_targets__target_id=9a8c6
extra_human_descriptions = []
for m2m_key in request.args:
if m2m_key.startswith("_m2m_"):
rest = m2m_key.split("_m2m_", 1)[1]
m2m_table, other_column = rest.split("__", 1)
m2m_table_info = self.ds.inspect()[name]["tables"][m2m_table]
outgoing_fks = m2m_table_info["foreign_keys"]["outgoing"]
fk_to_us = [fk for fk in outgoing_fks if fk["other_table"] == table][0]
# fk_to_other = [
# fk for fk in outgoing_fks
# if fk["other_table"] != table
# and fk["other_column"] == other_column
# ][0]
for value in request.args[m2m_key]:
# Figure out what the columns are in that m2m table
where_clauses.append(
'{our_pk} in (select {our_column} from {m2m_table} where {other_column} = "{value}")'.format(
m2m_table=escape_sqlite(m2m_table),
our_pk=fk_to_us["other_column"],
our_column=fk_to_us["column"],
other_column=escape_sqlite(other_column),
value=value,
)
)
extra_human_descriptions.append(
'{} contains "{}"'.format(m2m_table, value)
)
# _search support: # _search support:
fts_table = info[name]["tables"].get(table, {}).get("fts_table") fts_table = info[name]["tables"].get(table, {}).get("fts_table")
search_args = dict( search_args = dict(
@ -719,6 +748,9 @@ class TableView(RowTableShared):
[b for b in [human_description_en, sorted_by] if b] [b for b in [human_description_en, sorted_by] if b]
) )
if extra_human_descriptions:
human_description_en += " and ".join(extra_human_descriptions)
async def extra_template(): async def extra_template():
display_columns, display_rows = await self.display_columns_and_rows( display_columns, display_rows = await self.display_columns_and_rows(
name, name,