feat(导出): 添加Markdown导出功能并支持_format参数

添加Markdown格式导出功能,包括导出链接和选项表单
同时修改多处视图以支持通过_format参数指定导出格式
This commit is contained in:
muyusajiangtian 2026-04-29 11:52:10 +08:00
commit 3bc4560a75
5 changed files with 1601 additions and 5 deletions

View file

@ -124,7 +124,7 @@
<p><a class="not-underlined" title="{{ query.sql }}" href="{{ urls.database(database) }}?{{ {'sql': query.sql}|urlencode|safe }}{% if query.params %}&amp;{{ query.params|urlencode|safe }}{% endif %}">&#x270e; <span class="underlined">View and edit SQL</span></a></p>
{% endif %}
<p class="export-links">This data as {% for name, url in renderers.items() %}<a href="{{ url }}">{{ name }}</a>{{ ", " if not loop.last }}{% endfor %}{% if display_rows %}, <a href="{{ url_csv }}">CSV</a> (<a href="#export">advanced</a>){% endif %}</p>
<p class="export-links">This data as {% for name, url in renderers.items() %}<a href="{{ url }}">{{ name }}</a>{{ ", " if not loop.last }}{% endfor %}{% if display_rows %}, <a href="{{ url_csv }}">CSV</a> (<a href="#export">advanced</a>), <a href="{{ url_markdown }}">Markdown</a> (<a href="#export-markdown">advanced</a>){% endif %}</p>
{% if suggested_facets %}
{% include "_suggested_facets.html" %}
@ -186,6 +186,20 @@ window._setColumnTypeData = {{ set_column_type_ui|tojson }};
{% endfor %}
</p>
</form>
<div id="export-markdown" class="advanced-export">
<form class="core" action="{{ url_markdown_path }}" method="get">
<p>
Markdown options:
{% if expandable_columns %}<label><input type="checkbox" name="_labels" checked> expand labels</label>{% endif %}
{% if next_url and settings.allow_csv_stream %}<label><input type="checkbox" name="_stream"> export all rows (unlimited)</label>{% endif %}
<label>Max rows: <input type="number" name="_max_rows" value="500" min="0" max="10000" style="width: 80px;"></label>
<input type="submit" value="Export Markdown">
{% for key, value in url_markdown_hidden_args %}
<input type="hidden" name="{{ key }}" value="{{ value }}">
{% endfor %}
</p>
</form>
</div>
</div>
{% endif %}

View file

@ -206,16 +206,21 @@ class DataView(BaseView):
async def as_csv(self, request, database):
return await stream_csv(self.ds, self.data, request, database)
async def as_markdown(self, request, database):
return await stream_markdown(self.ds, self.data, request, database)
async def get(self, request):
db = await self.ds.resolve_database(request)
database = db.name
database_route = db.route
_format = request.url_vars["format"]
_format = request.url_vars["format"] or request.args.get("_format")
data_kwargs = {}
if _format == "csv":
return await self.as_csv(request, database_route)
elif _format == "markdown":
return await self.as_markdown(request, database_route)
if _format is None:
# HTML views default to expanding all foreign key labels

View file

@ -40,7 +40,7 @@ from . import Context
class DatabaseView(View):
async def get(self, request, datasette):
format_ = request.url_vars.get("format") or "html"
format_ = request.url_vars.get("format") or request.args.get("_format") or "html"
await datasette.refresh_schemas()
@ -591,7 +591,7 @@ class QueryView(View):
if params.get("_timelimit"):
extra_args["custom_time_limit"] = int(params["_timelimit"])
format_ = request.url_vars.get("format") or "html"
format_ = request.url_vars.get("format") or request.args.get("_format") or "html"
query_error = None
results = None

View file

@ -976,7 +976,7 @@ async def table_view_traced(datasette, request):
if request.method == "POST":
return Response.text("Method not allowed", status=405)
format_ = request.url_vars.get("format") or "html"
format_ = request.url_vars.get("format") or request.args.get("_format") or "html"
extra_extras = None
context_for_html_hack = False
default_labels = False
@ -2072,6 +2072,12 @@ async def table_view_data(
path_with_format(request=request, format="csv", extra_qs=url_csv_args)
)
url_csv_path = url_csv.split("?")[0]
# Markdown export URL
url_markdown_args = {**url_labels_extra}
url_markdown = datasette.urls.path(
path_with_format(request=request, format="markdown", extra_qs=url_markdown_args)
)
url_markdown_path = url_markdown.split("?")[0]
data.update(
{
"url_csv": url_csv,
@ -2082,6 +2088,13 @@ async def table_view_data(
if key not in ("_labels", "_facet", "_size")
]
+ [("_size", "max")],
"url_markdown": url_markdown,
"url_markdown_path": url_markdown_path,
"url_markdown_hidden_args": [
(key, value)
for key, value in urllib.parse.parse_qsl(request.query_string)
if key not in ("_labels", "_facet", "_size", "_max_rows")
],
}
)
# if no sort specified AND table has a single primary key,

1564
test.md Normal file

File diff suppressed because it is too large Load diff