Deployed 6b127d9 to v3.0 with Zensical 0.0.31 and mike 2.2.0+zensical-0.1.0

This commit is contained in:
github-actions[bot]
2026-04-04 23:15:54 +00:00
parent 07289c015a
commit b8da326810
3 changed files with 284 additions and 169 deletions

View File

@@ -2483,112 +2483,163 @@
</span><span id="__span-18-3"><a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a> <span class="n">search_fields</span><span class="o">=</span><span class="p">[</span><span class="n">User</span><span class="o">.</span><span class="n">country</span><span class="p">],</span> </span><span id="__span-18-3"><a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a> <span class="n">search_fields</span><span class="o">=</span><span class="p">[</span><span class="n">User</span><span class="o">.</span><span class="n">country</span><span class="p">],</span>
</span><span id="__span-18-4"><a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-4"></a><span class="p">)</span> </span><span id="__span-18-4"><a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-4"></a><span class="p">)</span>
</span></code></pre></div> </span></code></pre></div>
<p>This allows searching with both <a href="../../reference/crud/#fastapi_toolsets.crud.factory.AsyncCrud.offset_paginate"><code>offset_paginate</code></a> and <a href="../../reference/crud/#fastapi_toolsets.crud.factory.AsyncCrud.cursor_paginate"><code>cursor_paginate</code></a>:</p> <p>Or via the dependency to narrow which fields are exposed as query parameters:</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-19-1"><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="nd">@router</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span> <div class="language-python highlight"><pre><span></span><code><span id="__span-19-1"><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="n">params</span> <span class="o">=</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate_params</span><span class="p">(</span><span class="n">search_fields</span><span class="o">=</span><span class="p">[</span><span class="n">Post</span><span class="o">.</span><span class="n">title</span><span class="p">])</span>
</span><span id="__span-19-2"><a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_users</span><span class="p">(</span>
</span><span id="__span-19-3"><a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a> <span class="n">session</span><span class="p">:</span> <span class="n">SessionDep</span><span class="p">,</span>
</span><span id="__span-19-4"><a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a> <span class="n">params</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span><span class="nb">dict</span><span class="p">,</span> <span class="n">Depends</span><span class="p">(</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate_params</span><span class="p">())],</span>
</span><span id="__span-19-5"><a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">OffsetPaginatedResponse</span><span class="p">[</span><span class="n">UserRead</span><span class="p">]:</span>
</span><span id="__span-19-6"><a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-6"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">UserRead</span><span class="p">)</span>
</span></code></pre></div> </span></code></pre></div>
<p>This allows searching with both <a href="../../reference/crud/#fastapi_toolsets.crud.factory.AsyncCrud.offset_paginate"><code>offset_paginate</code></a> and <a href="../../reference/crud/#fastapi_toolsets.crud.factory.AsyncCrud.cursor_paginate"><code>cursor_paginate</code></a>:</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-20-1"><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="nd">@router</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span> <div class="language-python highlight"><pre><span></span><code><span id="__span-20-1"><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="nd">@router</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
</span><span id="__span-20-2"><a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_users</span><span class="p">(</span> </span><span id="__span-20-2"><a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_users</span><span class="p">(</span>
</span><span id="__span-20-3"><a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a> <span class="n">session</span><span class="p">:</span> <span class="n">SessionDep</span><span class="p">,</span> </span><span id="__span-20-3"><a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a> <span class="n">session</span><span class="p">:</span> <span class="n">SessionDep</span><span class="p">,</span>
</span><span id="__span-20-4"><a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a> <span class="n">params</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span><span class="nb">dict</span><span class="p">,</span> <span class="n">Depends</span><span class="p">(</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">cursor_paginate_params</span><span class="p">())],</span> </span><span id="__span-20-4"><a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a> <span class="n">params</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span><span class="nb">dict</span><span class="p">,</span> <span class="n">Depends</span><span class="p">(</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate_params</span><span class="p">())],</span>
</span><span id="__span-20-5"><a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">CursorPaginatedResponse</span><span class="p">[</span><span class="n">UserRead</span><span class="p">]:</span> </span><span id="__span-20-5"><a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">OffsetPaginatedResponse</span><span class="p">[</span><span class="n">UserRead</span><span class="p">]:</span>
</span><span id="__span-20-6"><a id="__codelineno-20-6" name="__codelineno-20-6" href="#__codelineno-20-6"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">cursor_paginate</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">UserRead</span><span class="p">)</span> </span><span id="__span-20-6"><a id="__codelineno-20-6" name="__codelineno-20-6" href="#__codelineno-20-6"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">UserRead</span><span class="p">)</span>
</span></code></pre></div> </span></code></pre></div>
<h3 id="faceted-search">Faceted search<a class="headerlink" href="#faceted-search" title="Permanent link">&para;</a></h3> <div class="language-python highlight"><pre><span></span><code><span id="__span-21-1"><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="nd">@router</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
<div class="admonition info"> </span><span id="__span-21-2"><a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_users</span><span class="p">(</span>
<p class="admonition-title">Added in <code>v1.2</code></p> </span><span id="__span-21-3"><a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a> <span class="n">session</span><span class="p">:</span> <span class="n">SessionDep</span><span class="p">,</span>
</div> </span><span id="__span-21-4"><a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a> <span class="n">params</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span><span class="nb">dict</span><span class="p">,</span> <span class="n">Depends</span><span class="p">(</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">cursor_paginate_params</span><span class="p">())],</span>
<p>Declare <code>facet_fields</code> on the CRUD class to return distinct column values alongside paginated results. This is useful for populating filter dropdowns or building faceted search UIs.</p> </span><span id="__span-21-5"><a id="__codelineno-21-5" name="__codelineno-21-5" href="#__codelineno-21-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">CursorPaginatedResponse</span><span class="p">[</span><span class="n">UserRead</span><span class="p">]:</span>
<p>Facet fields use the same syntax as <code>searchable_fields</code> — direct columns or relationship tuples:</p> </span><span id="__span-21-6"><a id="__codelineno-21-6" name="__codelineno-21-6" href="#__codelineno-21-6"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">cursor_paginate</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">UserRead</span><span class="p">)</span>
<div class="language-python highlight"><pre><span></span><code><span id="__span-21-1"><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="n">UserCrud</span> <span class="o">=</span> <span class="n">CrudFactory</span><span class="p">(</span>
</span><span id="__span-21-2"><a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">User</span><span class="p">,</span>
</span><span id="__span-21-3"><a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a> <span class="n">facet_fields</span><span class="o">=</span><span class="p">[</span>
</span><span id="__span-21-4"><a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a> <span class="n">User</span><span class="o">.</span><span class="n">status</span><span class="p">,</span>
</span><span id="__span-21-5"><a id="__codelineno-21-5" name="__codelineno-21-5" href="#__codelineno-21-5"></a> <span class="n">User</span><span class="o">.</span><span class="n">country</span><span class="p">,</span>
</span><span id="__span-21-6"><a id="__codelineno-21-6" name="__codelineno-21-6" href="#__codelineno-21-6"></a> <span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">role</span><span class="p">,</span> <span class="n">Role</span><span class="o">.</span><span class="n">name</span><span class="p">),</span> <span class="c1"># value from a related model</span>
</span><span id="__span-21-7"><a id="__codelineno-21-7" name="__codelineno-21-7" href="#__codelineno-21-7"></a> <span class="p">],</span>
</span><span id="__span-21-8"><a id="__codelineno-21-8" name="__codelineno-21-8" href="#__codelineno-21-8"></a><span class="p">)</span>
</span></code></pre></div> </span></code></pre></div>
<p>You can override <code>facet_fields</code> per call:</p> <p>The dependency adds two query parameters to the endpoint:</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-22-1"><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a><span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate</span><span class="p">(</span> <table>
</span><span id="__span-22-2"><a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <thead>
</span><span id="__span-22-3"><a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a> <span class="n">facet_fields</span><span class="o">=</span><span class="p">[</span><span class="n">User</span><span class="o">.</span><span class="n">country</span><span class="p">],</span> <tr>
</span><span id="__span-22-4"><a id="__codelineno-22-4" name="__codelineno-22-4" href="#__codelineno-22-4"></a><span class="p">)</span> <th>Parameter</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>search</code></td>
<td><code>str \| null</code></td>
</tr>
<tr>
<td><code>search_column</code></td>
<td><code>str \| null</code></td>
</tr>
</tbody>
</table>
<div class="language-text highlight"><pre><span></span><code><span id="__span-22-1"><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a>GET /posts?search=hello → search all configured columns
</span><span id="__span-22-2"><a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a>GET /posts?search=hello&amp;search_column=title → search only Post.title
</span></code></pre></div> </span></code></pre></div>
<p>The distinct values are returned in the <code>filter_attributes</code> field of <a href="../../reference/schemas/#fastapi_toolsets.schemas.PaginatedResponse"><code>PaginatedResponse</code></a>:</p> <p>The available search column keys are returned in the <code>search_columns</code> field of <a href="../../reference/schemas/#fastapi_toolsets.schemas.PaginatedResponse"><code>PaginatedResponse</code></a>. Use them to populate a column picker in the UI, or to validate <code>search_column</code> values on the client side:</p>
<div class="language-json highlight"><pre><span></span><code><span id="__span-23-1"><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="p">{</span> <div class="language-json highlight"><pre><span></span><code><span id="__span-23-1"><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="p">{</span>
</span><span id="__span-23-2"><a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a><span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;SUCCESS&quot;</span><span class="p">,</span> </span><span id="__span-23-2"><a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a><span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;SUCCESS&quot;</span><span class="p">,</span>
</span><span id="__span-23-3"><a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a><span class="w"> </span><span class="nt">&quot;data&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;...&quot;</span><span class="p">],</span> </span><span id="__span-23-3"><a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a><span class="w"> </span><span class="nt">&quot;data&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;...&quot;</span><span class="p">],</span>
</span><span id="__span-23-4"><a id="__codelineno-23-4" name="__codelineno-23-4" href="#__codelineno-23-4"></a><span class="w"> </span><span class="nt">&quot;pagination&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">&quot;...&quot;</span><span class="w"> </span><span class="p">},</span> </span><span id="__span-23-4"><a id="__codelineno-23-4" name="__codelineno-23-4" href="#__codelineno-23-4"></a><span class="w"> </span><span class="nt">&quot;pagination&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">&quot;...&quot;</span><span class="w"> </span><span class="p">},</span>
</span><span id="__span-23-5"><a id="__codelineno-23-5" name="__codelineno-23-5" href="#__codelineno-23-5"></a><span class="w"> </span><span class="nt">&quot;filter_attributes&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span> </span><span id="__span-23-5"><a id="__codelineno-23-5" name="__codelineno-23-5" href="#__codelineno-23-5"></a><span class="w"> </span><span class="nt">&quot;search_columns&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;content&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;author__username&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;title&quot;</span><span class="p">]</span>
</span><span id="__span-23-6"><a id="__codelineno-23-6" name="__codelineno-23-6" href="#__codelineno-23-6"></a><span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;active&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;inactive&quot;</span><span class="p">],</span> </span><span id="__span-23-6"><a id="__codelineno-23-6" name="__codelineno-23-6" href="#__codelineno-23-6"></a><span class="p">}</span>
</span><span id="__span-23-7"><a id="__codelineno-23-7" name="__codelineno-23-7" href="#__codelineno-23-7"></a><span class="w"> </span><span class="nt">&quot;country&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;DE&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;FR&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;US&quot;</span><span class="p">],</span>
</span><span id="__span-23-8"><a id="__codelineno-23-8" name="__codelineno-23-8" href="#__codelineno-23-8"></a><span class="w"> </span><span class="nt">&quot;role__name&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;admin&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;editor&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;viewer&quot;</span><span class="p">]</span>
</span><span id="__span-23-9"><a id="__codelineno-23-9" name="__codelineno-23-9" href="#__codelineno-23-9"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-23-10"><a id="__codelineno-23-10" name="__codelineno-23-10" href="#__codelineno-23-10"></a><span class="p">}</span>
</span></code></pre></div> </span></code></pre></div>
<p>Use <code>filter_by</code> to pass the client's chosen filter values directly — no need to build SQLAlchemy conditions by hand. Any unknown key raises <a href="../../reference/exceptions/#fastapi_toolsets.exceptions.exceptions.InvalidFacetFilterError"><code>InvalidFacetFilterError</code></a>.</p>
<div class="admonition info"> <div class="admonition info">
<p class="admonition-title">The keys in <code>filter_by</code> are the same keys the client received in <code>filter_attributes</code>.</p> <p class="admonition-title">Key format uses <code>__</code> as a separator for relationship chains.</p>
<p>Keys use <code>__</code> as a separator for the full relationship chain. A direct column <code>User.status</code> produces <code>"status"</code>. A relationship tuple <code>(User.role, Role.name)</code> produces <code>"role__name"</code>. A deeper chain <code>(User.role, Role.permission, Permission.name)</code> produces <code>"role__permission__name"</code>.</p> <p>A direct column <code>Post.title</code> produces <code>"title"</code>. A relationship tuple <code>(Post.author, User.username)</code> produces <code>"author__username"</code>. An unknown <code>search_column</code> value raises <a href="../../reference/exceptions/#fastapi_toolsets.exceptions.exceptions.InvalidSearchColumnError"><code>InvalidSearchColumnError</code></a> (HTTP 422).</p>
</div> </div>
<p><code>filter_by</code> and <code>filters</code> can be combined — both are applied with AND logic.</p> <h3 id="faceted-search">Faceted search<a class="headerlink" href="#faceted-search" title="Permanent link">&para;</a></h3>
<p>Facet filtering is built into the consolidated params dependencies. When <code>filter=True</code> (the default), facet fields are exposed as query parameters and collected into <code>filter_by</code> automatically:</p> <div class="admonition info">
<div class="language-python highlight"><pre><span></span><code><span id="__span-24-1"><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">Annotated</span> <p class="admonition-title">Added in <code>v1.2</code></p>
</span><span id="__span-24-2"><a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a> </div>
</span><span id="__span-24-3"><a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a><span class="kn">from</span><span class="w"> </span><span class="nn">fastapi</span><span class="w"> </span><span class="kn">import</span> <span class="n">Depends</span> <p>Declare <code>facet_fields</code> on the CRUD class to return distinct column values alongside paginated results. This is useful for populating filter dropdowns or building faceted search UIs. Relationship traversal is supported via tuples, using the same syntax as <code>searchable_fields</code>:</p>
</span><span id="__span-24-4"><a id="__codelineno-24-4" name="__codelineno-24-4" href="#__codelineno-24-4"></a> <div class="language-python highlight"><pre><span></span><code><span id="__span-24-1"><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="n">UserCrud</span> <span class="o">=</span> <span class="n">CrudFactory</span><span class="p">(</span>
</span><span id="__span-24-5"><a id="__codelineno-24-5" name="__codelineno-24-5" href="#__codelineno-24-5"></a><span class="n">UserCrud</span> <span class="o">=</span> <span class="n">CrudFactory</span><span class="p">(</span> </span><span id="__span-24-2"><a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">User</span><span class="p">,</span>
</span><span id="__span-24-6"><a id="__codelineno-24-6" name="__codelineno-24-6" href="#__codelineno-24-6"></a> <span class="n">model</span><span class="o">=</span><span class="n">User</span><span class="p">,</span> </span><span id="__span-24-3"><a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a> <span class="n">facet_fields</span><span class="o">=</span><span class="p">[</span>
</span><span id="__span-24-7"><a id="__codelineno-24-7" name="__codelineno-24-7" href="#__codelineno-24-7"></a> <span class="n">facet_fields</span><span class="o">=</span><span class="p">[</span><span class="n">User</span><span class="o">.</span><span class="n">status</span><span class="p">,</span> <span class="n">User</span><span class="o">.</span><span class="n">country</span><span class="p">,</span> <span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">role</span><span class="p">,</span> <span class="n">Role</span><span class="o">.</span><span class="n">name</span><span class="p">)],</span> </span><span id="__span-24-4"><a id="__codelineno-24-4" name="__codelineno-24-4" href="#__codelineno-24-4"></a> <span class="n">User</span><span class="o">.</span><span class="n">status</span><span class="p">,</span>
</span><span id="__span-24-5"><a id="__codelineno-24-5" name="__codelineno-24-5" href="#__codelineno-24-5"></a> <span class="n">User</span><span class="o">.</span><span class="n">country</span><span class="p">,</span>
</span><span id="__span-24-6"><a id="__codelineno-24-6" name="__codelineno-24-6" href="#__codelineno-24-6"></a> <span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">role</span><span class="p">,</span> <span class="n">Role</span><span class="o">.</span><span class="n">name</span><span class="p">),</span> <span class="c1"># value from a related model</span>
</span><span id="__span-24-7"><a id="__codelineno-24-7" name="__codelineno-24-7" href="#__codelineno-24-7"></a> <span class="p">],</span>
</span><span id="__span-24-8"><a id="__codelineno-24-8" name="__codelineno-24-8" href="#__codelineno-24-8"></a><span class="p">)</span> </span><span id="__span-24-8"><a id="__codelineno-24-8" name="__codelineno-24-8" href="#__codelineno-24-8"></a><span class="p">)</span>
</span><span id="__span-24-9"><a id="__codelineno-24-9" name="__codelineno-24-9" href="#__codelineno-24-9"></a>
</span><span id="__span-24-10"><a id="__codelineno-24-10" name="__codelineno-24-10" href="#__codelineno-24-10"></a><span class="nd">@router</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">response_model_exclude_none</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="__span-24-11"><a id="__codelineno-24-11" name="__codelineno-24-11" href="#__codelineno-24-11"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">list_users</span><span class="p">(</span>
</span><span id="__span-24-12"><a id="__codelineno-24-12" name="__codelineno-24-12" href="#__codelineno-24-12"></a> <span class="n">session</span><span class="p">:</span> <span class="n">SessionDep</span><span class="p">,</span>
</span><span id="__span-24-13"><a id="__codelineno-24-13" name="__codelineno-24-13" href="#__codelineno-24-13"></a> <span class="n">params</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span><span class="nb">dict</span><span class="p">,</span> <span class="n">Depends</span><span class="p">(</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate_params</span><span class="p">())],</span>
</span><span id="__span-24-14"><a id="__codelineno-24-14" name="__codelineno-24-14" href="#__codelineno-24-14"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">OffsetPaginatedResponse</span><span class="p">[</span><span class="n">UserRead</span><span class="p">]:</span>
</span><span id="__span-24-15"><a id="__codelineno-24-15" name="__codelineno-24-15" href="#__codelineno-24-15"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate</span><span class="p">(</span>
</span><span id="__span-24-16"><a id="__codelineno-24-16" name="__codelineno-24-16" href="#__codelineno-24-16"></a> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span>
</span><span id="__span-24-17"><a id="__codelineno-24-17" name="__codelineno-24-17" href="#__codelineno-24-17"></a> <span class="o">**</span><span class="n">params</span><span class="p">,</span>
</span><span id="__span-24-18"><a id="__codelineno-24-18" name="__codelineno-24-18" href="#__codelineno-24-18"></a> <span class="n">schema</span><span class="o">=</span><span class="n">UserRead</span><span class="p">,</span>
</span><span id="__span-24-19"><a id="__codelineno-24-19" name="__codelineno-24-19" href="#__codelineno-24-19"></a> <span class="p">)</span>
</span></code></pre></div> </span></code></pre></div>
<p>Both single-value and multi-value query parameters work:</p> <p>You can override <code>facet_fields</code> per call:</p>
<div class="language-text highlight"><pre><span></span><code><span id="__span-25-1"><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a>GET /users?status=active → filter_by={&quot;status&quot;: [&quot;active&quot;]} <div class="language-python highlight"><pre><span></span><code><span id="__span-25-1"><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate</span><span class="p">(</span>
</span><span id="__span-25-2"><a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a>GET /users?status=active&amp;country=FR → filter_by={&quot;status&quot;: [&quot;active&quot;], &quot;country&quot;: [&quot;FR&quot;]} </span><span id="__span-25-2"><a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span>
</span><span id="__span-25-3"><a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a>GET /users?role__name=admin&amp;role__name=editor → filter_by={&quot;role__name&quot;: [&quot;admin&quot;, &quot;editor&quot;]} (IN clause) </span><span id="__span-25-3"><a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a> <span class="n">facet_fields</span><span class="o">=</span><span class="p">[</span><span class="n">User</span><span class="o">.</span><span class="n">country</span><span class="p">],</span>
</span><span id="__span-25-4"><a id="__codelineno-25-4" name="__codelineno-25-4" href="#__codelineno-25-4"></a><span class="p">)</span>
</span></code></pre></div> </span></code></pre></div>
<h2 id="sorting">Sorting<a class="headerlink" href="#sorting" title="Permanent link">&para;</a></h2> <p>Or via the dependency to narrow which fields are exposed as query parameters:</p>
<div class="admonition info"> <div class="language-python highlight"><pre><span></span><code><span id="__span-26-1"><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="n">params</span> <span class="o">=</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate_params</span><span class="p">(</span><span class="n">facet_fields</span><span class="o">=</span><span class="p">[</span><span class="n">User</span><span class="o">.</span><span class="n">country</span><span class="p">])</span>
<p class="admonition-title">Added in <code>v1.3</code></p>
</div>
<p>Declare <code>order_fields</code> on the CRUD class to expose client-driven column ordering via <code>order_by</code> and <code>order</code> query parameters.</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-26-1"><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="n">UserCrud</span> <span class="o">=</span> <span class="n">CrudFactory</span><span class="p">(</span>
</span><span id="__span-26-2"><a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">User</span><span class="p">,</span>
</span><span id="__span-26-3"><a id="__codelineno-26-3" name="__codelineno-26-3" href="#__codelineno-26-3"></a> <span class="n">order_fields</span><span class="o">=</span><span class="p">[</span>
</span><span id="__span-26-4"><a id="__codelineno-26-4" name="__codelineno-26-4" href="#__codelineno-26-4"></a> <span class="n">User</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
</span><span id="__span-26-5"><a id="__codelineno-26-5" name="__codelineno-26-5" href="#__codelineno-26-5"></a> <span class="n">User</span><span class="o">.</span><span class="n">created_at</span><span class="p">,</span>
</span><span id="__span-26-6"><a id="__codelineno-26-6" name="__codelineno-26-6" href="#__codelineno-26-6"></a> <span class="p">],</span>
</span><span id="__span-26-7"><a id="__codelineno-26-7" name="__codelineno-26-7" href="#__codelineno-26-7"></a><span class="p">)</span>
</span></code></pre></div> </span></code></pre></div>
<p>Ordering is built into the consolidated params dependencies. When <code>order=True</code> (the default), <code>order_by</code> and <code>order</code> query parameters are exposed and resolved into an <code>OrderByClause</code> automatically:</p> <p>Facet filtering is built into the consolidated params dependencies. When <code>filter=True</code> (the default), each facet field is exposed as a query parameter and values are collected into <code>filter_by</code> automatically:</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-27-1"><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">Annotated</span> <div class="language-python highlight"><pre><span></span><code><span id="__span-27-1"><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">Annotated</span>
</span><span id="__span-27-2"><a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a> </span><span id="__span-27-2"><a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a>
</span><span id="__span-27-3"><a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a><span class="kn">from</span><span class="w"> </span><span class="nn">fastapi</span><span class="w"> </span><span class="kn">import</span> <span class="n">Depends</span> </span><span id="__span-27-3"><a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a><span class="kn">from</span><span class="w"> </span><span class="nn">fastapi</span><span class="w"> </span><span class="kn">import</span> <span class="n">Depends</span>
</span><span id="__span-27-4"><a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a> </span><span id="__span-27-4"><a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a>
</span><span id="__span-27-5"><a id="__codelineno-27-5" name="__codelineno-27-5" href="#__codelineno-27-5"></a><span class="nd">@router</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span> </span><span id="__span-27-5"><a id="__codelineno-27-5" name="__codelineno-27-5" href="#__codelineno-27-5"></a><span class="nd">@router</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">response_model_exclude_none</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="__span-27-6"><a id="__codelineno-27-6" name="__codelineno-27-6" href="#__codelineno-27-6"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">list_users</span><span class="p">(</span> </span><span id="__span-27-6"><a id="__codelineno-27-6" name="__codelineno-27-6" href="#__codelineno-27-6"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">list_users</span><span class="p">(</span>
</span><span id="__span-27-7"><a id="__codelineno-27-7" name="__codelineno-27-7" href="#__codelineno-27-7"></a> <span class="n">session</span><span class="p">:</span> <span class="n">SessionDep</span><span class="p">,</span> </span><span id="__span-27-7"><a id="__codelineno-27-7" name="__codelineno-27-7" href="#__codelineno-27-7"></a> <span class="n">session</span><span class="p">:</span> <span class="n">SessionDep</span><span class="p">,</span>
</span><span id="__span-27-8"><a id="__codelineno-27-8" name="__codelineno-27-8" href="#__codelineno-27-8"></a> <span class="n">params</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span><span class="nb">dict</span><span class="p">,</span> <span class="n">Depends</span><span class="p">(</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate_params</span><span class="p">(</span> </span><span id="__span-27-8"><a id="__codelineno-27-8" name="__codelineno-27-8" href="#__codelineno-27-8"></a> <span class="n">params</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span><span class="nb">dict</span><span class="p">,</span> <span class="n">Depends</span><span class="p">(</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate_params</span><span class="p">())],</span>
</span><span id="__span-27-9"><a id="__codelineno-27-9" name="__codelineno-27-9" href="#__codelineno-27-9"></a> <span class="n">default_order_field</span><span class="o">=</span><span class="n">User</span><span class="o">.</span><span class="n">created_at</span><span class="p">,</span> </span><span id="__span-27-9"><a id="__codelineno-27-9" name="__codelineno-27-9" href="#__codelineno-27-9"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">OffsetPaginatedResponse</span><span class="p">[</span><span class="n">UserRead</span><span class="p">]:</span>
</span><span id="__span-27-10"><a id="__codelineno-27-10" name="__codelineno-27-10" href="#__codelineno-27-10"></a> <span class="p">))],</span> </span><span id="__span-27-10"><a id="__codelineno-27-10" name="__codelineno-27-10" href="#__codelineno-27-10"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">UserRead</span><span class="p">)</span>
</span><span id="__span-27-11"><a id="__codelineno-27-11" name="__codelineno-27-11" href="#__codelineno-27-11"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">OffsetPaginatedResponse</span><span class="p">[</span><span class="n">UserRead</span><span class="p">]:</span> </span></code></pre></div>
</span><span id="__span-27-12"><a id="__codelineno-27-12" name="__codelineno-27-12" href="#__codelineno-27-12"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">UserRead</span><span class="p">)</span> <div class="language-python highlight"><pre><span></span><code><span id="__span-28-1"><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="nd">@router</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">response_model_exclude_none</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="__span-28-2"><a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">list_users</span><span class="p">(</span>
</span><span id="__span-28-3"><a id="__codelineno-28-3" name="__codelineno-28-3" href="#__codelineno-28-3"></a> <span class="n">session</span><span class="p">:</span> <span class="n">SessionDep</span><span class="p">,</span>
</span><span id="__span-28-4"><a id="__codelineno-28-4" name="__codelineno-28-4" href="#__codelineno-28-4"></a> <span class="n">params</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span><span class="nb">dict</span><span class="p">,</span> <span class="n">Depends</span><span class="p">(</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">cursor_paginate_params</span><span class="p">())],</span>
</span><span id="__span-28-5"><a id="__codelineno-28-5" name="__codelineno-28-5" href="#__codelineno-28-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">CursorPaginatedResponse</span><span class="p">[</span><span class="n">UserRead</span><span class="p">]:</span>
</span><span id="__span-28-6"><a id="__codelineno-28-6" name="__codelineno-28-6" href="#__codelineno-28-6"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">cursor_paginate</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">UserRead</span><span class="p">)</span>
</span></code></pre></div>
<p>Both single-value and multi-value query parameters work:</p>
<div class="language-text highlight"><pre><span></span><code><span id="__span-29-1"><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a>GET /users?status=active → filter_by={&quot;status&quot;: [&quot;active&quot;]}
</span><span id="__span-29-2"><a id="__codelineno-29-2" name="__codelineno-29-2" href="#__codelineno-29-2"></a>GET /users?status=active&amp;country=FR → filter_by={&quot;status&quot;: [&quot;active&quot;], &quot;country&quot;: [&quot;FR&quot;]}
</span><span id="__span-29-3"><a id="__codelineno-29-3" name="__codelineno-29-3" href="#__codelineno-29-3"></a>GET /users?role__name=admin&amp;role__name=editor → filter_by={&quot;role__name&quot;: [&quot;admin&quot;, &quot;editor&quot;]} (IN clause)
</span></code></pre></div>
<p><code>filter_by</code> and <code>filters</code> can be combined — both are applied with AND logic.</p>
<p>The distinct values for each facet field are returned in the <code>filter_attributes</code> field of <a href="../../reference/schemas/#fastapi_toolsets.schemas.PaginatedResponse"><code>PaginatedResponse</code></a>. Use them to populate filter dropdowns in the UI, or to validate <code>filter_by</code> keys on the client side:</p>
<div class="language-json highlight"><pre><span></span><code><span id="__span-30-1"><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a><span class="p">{</span>
</span><span id="__span-30-2"><a id="__codelineno-30-2" name="__codelineno-30-2" href="#__codelineno-30-2"></a><span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;SUCCESS&quot;</span><span class="p">,</span>
</span><span id="__span-30-3"><a id="__codelineno-30-3" name="__codelineno-30-3" href="#__codelineno-30-3"></a><span class="w"> </span><span class="nt">&quot;data&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;...&quot;</span><span class="p">],</span>
</span><span id="__span-30-4"><a id="__codelineno-30-4" name="__codelineno-30-4" href="#__codelineno-30-4"></a><span class="w"> </span><span class="nt">&quot;pagination&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">&quot;...&quot;</span><span class="w"> </span><span class="p">},</span>
</span><span id="__span-30-5"><a id="__codelineno-30-5" name="__codelineno-30-5" href="#__codelineno-30-5"></a><span class="w"> </span><span class="nt">&quot;filter_attributes&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-30-6"><a id="__codelineno-30-6" name="__codelineno-30-6" href="#__codelineno-30-6"></a><span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;active&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;inactive&quot;</span><span class="p">],</span>
</span><span id="__span-30-7"><a id="__codelineno-30-7" name="__codelineno-30-7" href="#__codelineno-30-7"></a><span class="w"> </span><span class="nt">&quot;country&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;DE&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;FR&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;US&quot;</span><span class="p">],</span>
</span><span id="__span-30-8"><a id="__codelineno-30-8" name="__codelineno-30-8" href="#__codelineno-30-8"></a><span class="w"> </span><span class="nt">&quot;role__name&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;admin&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;editor&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;viewer&quot;</span><span class="p">]</span>
</span><span id="__span-30-9"><a id="__codelineno-30-9" name="__codelineno-30-9" href="#__codelineno-30-9"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-30-10"><a id="__codelineno-30-10" name="__codelineno-30-10" href="#__codelineno-30-10"></a><span class="p">}</span>
</span></code></pre></div>
<div class="admonition info">
<p class="admonition-title">Key format uses <code>__</code> as a separator for relationship chains.</p>
<p>A direct column <code>User.status</code> produces <code>"status"</code>. A relationship tuple <code>(User.role, Role.name)</code> produces <code>"role__name"</code>. A deeper chain <code>(User.role, Role.permission, Permission.name)</code> produces <code>"role__permission__name"</code>. An unknown <code>filter_by</code> key raises <a href="../../reference/exceptions/#fastapi_toolsets.exceptions.exceptions.InvalidFacetFilterError"><code>InvalidFacetFilterError</code></a> (HTTP 422).</p>
</div>
<h2 id="sorting">Sorting<a class="headerlink" href="#sorting" title="Permanent link">&para;</a></h2>
<div class="admonition info">
<p class="admonition-title">Added in <code>v1.3</code></p>
</div>
<p>Declare <code>order_fields</code> on the CRUD class. Relationship traversal is supported via tuples, using the same syntax as <code>searchable_fields</code> and <code>facet_fields</code>:</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-31-1"><a id="__codelineno-31-1" name="__codelineno-31-1" href="#__codelineno-31-1"></a><span class="n">UserCrud</span> <span class="o">=</span> <span class="n">CrudFactory</span><span class="p">(</span>
</span><span id="__span-31-2"><a id="__codelineno-31-2" name="__codelineno-31-2" href="#__codelineno-31-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">User</span><span class="p">,</span>
</span><span id="__span-31-3"><a id="__codelineno-31-3" name="__codelineno-31-3" href="#__codelineno-31-3"></a> <span class="n">order_fields</span><span class="o">=</span><span class="p">[</span>
</span><span id="__span-31-4"><a id="__codelineno-31-4" name="__codelineno-31-4" href="#__codelineno-31-4"></a> <span class="n">User</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
</span><span id="__span-31-5"><a id="__codelineno-31-5" name="__codelineno-31-5" href="#__codelineno-31-5"></a> <span class="n">User</span><span class="o">.</span><span class="n">created_at</span><span class="p">,</span>
</span><span id="__span-31-6"><a id="__codelineno-31-6" name="__codelineno-31-6" href="#__codelineno-31-6"></a> <span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">role</span><span class="p">,</span> <span class="n">Role</span><span class="o">.</span><span class="n">name</span><span class="p">),</span> <span class="c1"># sort by a related model column</span>
</span><span id="__span-31-7"><a id="__codelineno-31-7" name="__codelineno-31-7" href="#__codelineno-31-7"></a> <span class="p">],</span>
</span><span id="__span-31-8"><a id="__codelineno-31-8" name="__codelineno-31-8" href="#__codelineno-31-8"></a><span class="p">)</span>
</span></code></pre></div>
<p>You can override <code>order_fields</code> per call:</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-32-1"><a id="__codelineno-32-1" name="__codelineno-32-1" href="#__codelineno-32-1"></a><span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate</span><span class="p">(</span>
</span><span id="__span-32-2"><a id="__codelineno-32-2" name="__codelineno-32-2" href="#__codelineno-32-2"></a> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span>
</span><span id="__span-32-3"><a id="__codelineno-32-3" name="__codelineno-32-3" href="#__codelineno-32-3"></a> <span class="n">order_fields</span><span class="o">=</span><span class="p">[</span><span class="n">User</span><span class="o">.</span><span class="n">name</span><span class="p">],</span>
</span><span id="__span-32-4"><a id="__codelineno-32-4" name="__codelineno-32-4" href="#__codelineno-32-4"></a><span class="p">)</span>
</span></code></pre></div>
<p>Or via the dependency to narrow which fields are exposed as query parameters:</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-33-1"><a id="__codelineno-33-1" name="__codelineno-33-1" href="#__codelineno-33-1"></a><span class="n">params</span> <span class="o">=</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate_params</span><span class="p">(</span><span class="n">order_fields</span><span class="o">=</span><span class="p">[</span><span class="n">User</span><span class="o">.</span><span class="n">name</span><span class="p">])</span>
</span></code></pre></div>
<p>Sorting is built into the consolidated params dependencies. When <code>order=True</code> (the default), <code>order_by</code> and <code>order</code> query parameters are exposed and resolved into an <code>OrderByClause</code> automatically:</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-34-1"><a id="__codelineno-34-1" name="__codelineno-34-1" href="#__codelineno-34-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">Annotated</span>
</span><span id="__span-34-2"><a id="__codelineno-34-2" name="__codelineno-34-2" href="#__codelineno-34-2"></a>
</span><span id="__span-34-3"><a id="__codelineno-34-3" name="__codelineno-34-3" href="#__codelineno-34-3"></a><span class="kn">from</span><span class="w"> </span><span class="nn">fastapi</span><span class="w"> </span><span class="kn">import</span> <span class="n">Depends</span>
</span><span id="__span-34-4"><a id="__codelineno-34-4" name="__codelineno-34-4" href="#__codelineno-34-4"></a>
</span><span id="__span-34-5"><a id="__codelineno-34-5" name="__codelineno-34-5" href="#__codelineno-34-5"></a><span class="nd">@router</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
</span><span id="__span-34-6"><a id="__codelineno-34-6" name="__codelineno-34-6" href="#__codelineno-34-6"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">list_users</span><span class="p">(</span>
</span><span id="__span-34-7"><a id="__codelineno-34-7" name="__codelineno-34-7" href="#__codelineno-34-7"></a> <span class="n">session</span><span class="p">:</span> <span class="n">SessionDep</span><span class="p">,</span>
</span><span id="__span-34-8"><a id="__codelineno-34-8" name="__codelineno-34-8" href="#__codelineno-34-8"></a> <span class="n">params</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span><span class="nb">dict</span><span class="p">,</span> <span class="n">Depends</span><span class="p">(</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate_params</span><span class="p">())],</span>
</span><span id="__span-34-9"><a id="__codelineno-34-9" name="__codelineno-34-9" href="#__codelineno-34-9"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">OffsetPaginatedResponse</span><span class="p">[</span><span class="n">UserRead</span><span class="p">]:</span>
</span><span id="__span-34-10"><a id="__codelineno-34-10" name="__codelineno-34-10" href="#__codelineno-34-10"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">UserRead</span><span class="p">)</span>
</span></code></pre></div>
<div class="language-python highlight"><pre><span></span><code><span id="__span-35-1"><a id="__codelineno-35-1" name="__codelineno-35-1" href="#__codelineno-35-1"></a><span class="nd">@router</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
</span><span id="__span-35-2"><a id="__codelineno-35-2" name="__codelineno-35-2" href="#__codelineno-35-2"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">list_users</span><span class="p">(</span>
</span><span id="__span-35-3"><a id="__codelineno-35-3" name="__codelineno-35-3" href="#__codelineno-35-3"></a> <span class="n">session</span><span class="p">:</span> <span class="n">SessionDep</span><span class="p">,</span>
</span><span id="__span-35-4"><a id="__codelineno-35-4" name="__codelineno-35-4" href="#__codelineno-35-4"></a> <span class="n">params</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span><span class="nb">dict</span><span class="p">,</span> <span class="n">Depends</span><span class="p">(</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">cursor_paginate_params</span><span class="p">())],</span>
</span><span id="__span-35-5"><a id="__codelineno-35-5" name="__codelineno-35-5" href="#__codelineno-35-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">CursorPaginatedResponse</span><span class="p">[</span><span class="n">UserRead</span><span class="p">]:</span>
</span><span id="__span-35-6"><a id="__codelineno-35-6" name="__codelineno-35-6" href="#__codelineno-35-6"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">cursor_paginate</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">UserRead</span><span class="p">)</span>
</span></code></pre></div> </span></code></pre></div>
<p>The dependency adds two query parameters to the endpoint:</p> <p>The dependency adds two query parameters to the endpoint:</p>
<table> <table>
@@ -2601,7 +2652,7 @@
<tbody> <tbody>
<tr> <tr>
<td><code>order_by</code></td> <td><code>order_by</code></td>
<td><code>str | null</code></td> <td><code>str \| null</code></td>
</tr> </tr>
<tr> <tr>
<td><code>order</code></td> <td><code>order</code></td>
@@ -2609,13 +2660,25 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<div class="language-text highlight"><pre><span></span><code><span id="__span-28-1"><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a>GET /users?order_by=name&amp;order=asc → ORDER BY users.name ASC <div class="language-text highlight"><pre><span></span><code><span id="__span-36-1"><a id="__codelineno-36-1" name="__codelineno-36-1" href="#__codelineno-36-1"></a>GET /users?order_by=name&amp;order=asc → ORDER BY users.name ASC
</span><span id="__span-28-2"><a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a>GET /users?order_by=name&amp;order=desc → ORDER BY users.name DESC </span><span id="__span-36-2"><a id="__codelineno-36-2" name="__codelineno-36-2" href="#__codelineno-36-2"></a>GET /users?order_by=role__name&amp;order=desc → LEFT JOIN roles ON ... ORDER BY roles.name DESC
</span></code></pre></div> </span></code></pre></div>
<p>An unknown <code>order_by</code> value raises <a href="../../reference/exceptions/#fastapi_toolsets.exceptions.exceptions.InvalidOrderFieldError"><code>InvalidOrderFieldError</code></a> (HTTP 422).</p> <div class="admonition info">
<p>You can also pass <code>order_fields</code> directly to override the class-level defaults:</p> <p class="admonition-title">Relationship tuples are joined automatically.</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-29-1"><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a><span class="n">params</span> <span class="o">=</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate_params</span><span class="p">(</span><span class="n">order_fields</span><span class="o">=</span><span class="p">[</span><span class="n">User</span><span class="o">.</span><span class="n">name</span><span class="p">])</span> <p>When a relation field is selected, the related table is LEFT OUTER JOINed automatically. An unknown <code>order_by</code> value raises <a href="../../reference/exceptions/#fastapi_toolsets.exceptions.exceptions.InvalidOrderFieldError"><code>InvalidOrderFieldError</code></a> (HTTP 422).</p>
</div>
<p>The available sort keys are returned in the <code>order_columns</code> field of <a href="../../reference/schemas/#fastapi_toolsets.schemas.PaginatedResponse"><code>PaginatedResponse</code></a>. Use them to populate a sort picker in the UI, or to validate <code>order_by</code> values on the client side:</p>
<div class="language-json highlight"><pre><span></span><code><span id="__span-37-1"><a id="__codelineno-37-1" name="__codelineno-37-1" href="#__codelineno-37-1"></a><span class="p">{</span>
</span><span id="__span-37-2"><a id="__codelineno-37-2" name="__codelineno-37-2" href="#__codelineno-37-2"></a><span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;SUCCESS&quot;</span><span class="p">,</span>
</span><span id="__span-37-3"><a id="__codelineno-37-3" name="__codelineno-37-3" href="#__codelineno-37-3"></a><span class="w"> </span><span class="nt">&quot;data&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;...&quot;</span><span class="p">],</span>
</span><span id="__span-37-4"><a id="__codelineno-37-4" name="__codelineno-37-4" href="#__codelineno-37-4"></a><span class="w"> </span><span class="nt">&quot;pagination&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">&quot;...&quot;</span><span class="w"> </span><span class="p">},</span>
</span><span id="__span-37-5"><a id="__codelineno-37-5" name="__codelineno-37-5" href="#__codelineno-37-5"></a><span class="w"> </span><span class="nt">&quot;order_columns&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;created_at&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;name&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;role__name&quot;</span><span class="p">]</span>
</span><span id="__span-37-6"><a id="__codelineno-37-6" name="__codelineno-37-6" href="#__codelineno-37-6"></a><span class="p">}</span>
</span></code></pre></div> </span></code></pre></div>
<div class="admonition info">
<p class="admonition-title">Key format uses <code>__</code> as a separator for relationship chains.</p>
<p>A direct column <code>User.name</code> produces <code>"name"</code>. A relationship tuple <code>(User.role, Role.name)</code> produces <code>"role__name"</code>.</p>
</div>
<h2 id="relationship-loading">Relationship loading<a class="headerlink" href="#relationship-loading" title="Permanent link">&para;</a></h2> <h2 id="relationship-loading">Relationship loading<a class="headerlink" href="#relationship-loading" title="Permanent link">&para;</a></h2>
<div class="admonition info"> <div class="admonition info">
<p class="admonition-title">Added in <code>v1.1</code></p> <p class="admonition-title">Added in <code>v1.1</code></p>
@@ -2625,71 +2688,71 @@
<p class="admonition-title">Warning</p> <p class="admonition-title">Warning</p>
<p>Avoid using <code>lazy="selectin"</code> on model relationships. It fires silently on every query, cannot be disabled per-call, and can cause unexpected cascading loads through deep relationship chains. Use <code>default_load_options</code> instead.</p> <p>Avoid using <code>lazy="selectin"</code> on model relationships. It fires silently on every query, cannot be disabled per-call, and can cause unexpected cascading loads through deep relationship chains. Use <code>default_load_options</code> instead.</p>
</div> </div>
<div class="language-python highlight"><pre><span></span><code><span id="__span-30-1"><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">sqlalchemy.orm</span><span class="w"> </span><span class="kn">import</span> <span class="n">selectinload</span> <div class="language-python highlight"><pre><span></span><code><span id="__span-38-1"><a id="__codelineno-38-1" name="__codelineno-38-1" href="#__codelineno-38-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">sqlalchemy.orm</span><span class="w"> </span><span class="kn">import</span> <span class="n">selectinload</span>
</span><span id="__span-30-2"><a id="__codelineno-30-2" name="__codelineno-30-2" href="#__codelineno-30-2"></a> </span><span id="__span-38-2"><a id="__codelineno-38-2" name="__codelineno-38-2" href="#__codelineno-38-2"></a>
</span><span id="__span-30-3"><a id="__codelineno-30-3" name="__codelineno-30-3" href="#__codelineno-30-3"></a><span class="n">ArticleCrud</span> <span class="o">=</span> <span class="n">CrudFactory</span><span class="p">(</span> </span><span id="__span-38-3"><a id="__codelineno-38-3" name="__codelineno-38-3" href="#__codelineno-38-3"></a><span class="n">ArticleCrud</span> <span class="o">=</span> <span class="n">CrudFactory</span><span class="p">(</span>
</span><span id="__span-30-4"><a id="__codelineno-30-4" name="__codelineno-30-4" href="#__codelineno-30-4"></a> <span class="n">model</span><span class="o">=</span><span class="n">Article</span><span class="p">,</span> </span><span id="__span-38-4"><a id="__codelineno-38-4" name="__codelineno-38-4" href="#__codelineno-38-4"></a> <span class="n">model</span><span class="o">=</span><span class="n">Article</span><span class="p">,</span>
</span><span id="__span-30-5"><a id="__codelineno-30-5" name="__codelineno-30-5" href="#__codelineno-30-5"></a> <span class="n">default_load_options</span><span class="o">=</span><span class="p">[</span> </span><span id="__span-38-5"><a id="__codelineno-38-5" name="__codelineno-38-5" href="#__codelineno-38-5"></a> <span class="n">default_load_options</span><span class="o">=</span><span class="p">[</span>
</span><span id="__span-30-6"><a id="__codelineno-30-6" name="__codelineno-30-6" href="#__codelineno-30-6"></a> <span class="n">selectinload</span><span class="p">(</span><span class="n">Article</span><span class="o">.</span><span class="n">category</span><span class="p">),</span> </span><span id="__span-38-6"><a id="__codelineno-38-6" name="__codelineno-38-6" href="#__codelineno-38-6"></a> <span class="n">selectinload</span><span class="p">(</span><span class="n">Article</span><span class="o">.</span><span class="n">category</span><span class="p">),</span>
</span><span id="__span-30-7"><a id="__codelineno-30-7" name="__codelineno-30-7" href="#__codelineno-30-7"></a> <span class="n">selectinload</span><span class="p">(</span><span class="n">Article</span><span class="o">.</span><span class="n">tags</span><span class="p">),</span> </span><span id="__span-38-7"><a id="__codelineno-38-7" name="__codelineno-38-7" href="#__codelineno-38-7"></a> <span class="n">selectinload</span><span class="p">(</span><span class="n">Article</span><span class="o">.</span><span class="n">tags</span><span class="p">),</span>
</span><span id="__span-30-8"><a id="__codelineno-30-8" name="__codelineno-30-8" href="#__codelineno-30-8"></a> <span class="p">],</span> </span><span id="__span-38-8"><a id="__codelineno-38-8" name="__codelineno-38-8" href="#__codelineno-38-8"></a> <span class="p">],</span>
</span><span id="__span-30-9"><a id="__codelineno-30-9" name="__codelineno-30-9" href="#__codelineno-30-9"></a><span class="p">)</span> </span><span id="__span-38-9"><a id="__codelineno-38-9" name="__codelineno-38-9" href="#__codelineno-38-9"></a><span class="p">)</span>
</span></code></pre></div> </span></code></pre></div>
<p><code>default_load_options</code> applies automatically to all read operations (<code>get</code>, <code>first</code>, <code>get_multi</code>, <code>offset_paginate</code>, <code>cursor_paginate</code>). When <code>load_options</code> is passed at call-site, it <strong>fully replaces</strong> <code>default_load_options</code> for that query — giving you precise per-call control:</p> <p><code>default_load_options</code> applies automatically to all read operations (<code>get</code>, <code>first</code>, <code>get_multi</code>, <code>offset_paginate</code>, <code>cursor_paginate</code>). When <code>load_options</code> is passed at call-site, it <strong>fully replaces</strong> <code>default_load_options</code> for that query — giving you precise per-call control:</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-31-1"><a id="__codelineno-31-1" name="__codelineno-31-1" href="#__codelineno-31-1"></a><span class="c1"># Only loads category, tags are not loaded</span> <div class="language-python highlight"><pre><span></span><code><span id="__span-39-1"><a id="__codelineno-39-1" name="__codelineno-39-1" href="#__codelineno-39-1"></a><span class="c1"># Only loads category, tags are not loaded</span>
</span><span id="__span-31-2"><a id="__codelineno-31-2" name="__codelineno-31-2" href="#__codelineno-31-2"></a><span class="n">article</span> <span class="o">=</span> <span class="k">await</span> <span class="n">ArticleCrud</span><span class="o">.</span><span class="n">get</span><span class="p">(</span> </span><span id="__span-39-2"><a id="__codelineno-39-2" name="__codelineno-39-2" href="#__codelineno-39-2"></a><span class="n">article</span> <span class="o">=</span> <span class="k">await</span> <span class="n">ArticleCrud</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
</span><span id="__span-31-3"><a id="__codelineno-31-3" name="__codelineno-31-3" href="#__codelineno-31-3"></a> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> </span><span id="__span-39-3"><a id="__codelineno-39-3" name="__codelineno-39-3" href="#__codelineno-39-3"></a> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span>
</span><span id="__span-31-4"><a id="__codelineno-31-4" name="__codelineno-31-4" href="#__codelineno-31-4"></a> <span class="n">filters</span><span class="o">=</span><span class="p">[</span><span class="n">Article</span><span class="o">.</span><span class="n">id</span> <span class="o">==</span> <span class="n">article_id</span><span class="p">],</span> </span><span id="__span-39-4"><a id="__codelineno-39-4" name="__codelineno-39-4" href="#__codelineno-39-4"></a> <span class="n">filters</span><span class="o">=</span><span class="p">[</span><span class="n">Article</span><span class="o">.</span><span class="n">id</span> <span class="o">==</span> <span class="n">article_id</span><span class="p">],</span>
</span><span id="__span-31-5"><a id="__codelineno-31-5" name="__codelineno-31-5" href="#__codelineno-31-5"></a> <span class="n">load_options</span><span class="o">=</span><span class="p">[</span><span class="n">selectinload</span><span class="p">(</span><span class="n">Article</span><span class="o">.</span><span class="n">category</span><span class="p">)],</span> </span><span id="__span-39-5"><a id="__codelineno-39-5" name="__codelineno-39-5" href="#__codelineno-39-5"></a> <span class="n">load_options</span><span class="o">=</span><span class="p">[</span><span class="n">selectinload</span><span class="p">(</span><span class="n">Article</span><span class="o">.</span><span class="n">category</span><span class="p">)],</span>
</span><span id="__span-31-6"><a id="__codelineno-31-6" name="__codelineno-31-6" href="#__codelineno-31-6"></a><span class="p">)</span> </span><span id="__span-39-6"><a id="__codelineno-39-6" name="__codelineno-39-6" href="#__codelineno-39-6"></a><span class="p">)</span>
</span><span id="__span-31-7"><a id="__codelineno-31-7" name="__codelineno-31-7" href="#__codelineno-31-7"></a> </span><span id="__span-39-7"><a id="__codelineno-39-7" name="__codelineno-39-7" href="#__codelineno-39-7"></a>
</span><span id="__span-31-8"><a id="__codelineno-31-8" name="__codelineno-31-8" href="#__codelineno-31-8"></a><span class="c1"># Loads nothing — useful for write-then-refresh flows or lightweight checks</span> </span><span id="__span-39-8"><a id="__codelineno-39-8" name="__codelineno-39-8" href="#__codelineno-39-8"></a><span class="c1"># Loads nothing — useful for write-then-refresh flows or lightweight checks</span>
</span><span id="__span-31-9"><a id="__codelineno-31-9" name="__codelineno-31-9" href="#__codelineno-31-9"></a><span class="n">articles</span> <span class="o">=</span> <span class="k">await</span> <span class="n">ArticleCrud</span><span class="o">.</span><span class="n">get_multi</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="n">load_options</span><span class="o">=</span><span class="p">[])</span> </span><span id="__span-39-9"><a id="__codelineno-39-9" name="__codelineno-39-9" href="#__codelineno-39-9"></a><span class="n">articles</span> <span class="o">=</span> <span class="k">await</span> <span class="n">ArticleCrud</span><span class="o">.</span><span class="n">get_multi</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="n">load_options</span><span class="o">=</span><span class="p">[])</span>
</span></code></pre></div> </span></code></pre></div>
<h2 id="many-to-many-relationships">Many-to-many relationships<a class="headerlink" href="#many-to-many-relationships" title="Permanent link">&para;</a></h2> <h2 id="many-to-many-relationships">Many-to-many relationships<a class="headerlink" href="#many-to-many-relationships" title="Permanent link">&para;</a></h2>
<p>Use <code>m2m_fields</code> to map schema fields containing lists of IDs to SQLAlchemy relationships. The CRUD class resolves and validates all IDs before persisting:</p> <p>Use <code>m2m_fields</code> to map schema fields containing lists of IDs to SQLAlchemy relationships. The CRUD class resolves and validates all IDs before persisting:</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-32-1"><a id="__codelineno-32-1" name="__codelineno-32-1" href="#__codelineno-32-1"></a><span class="n">PostCrud</span> <span class="o">=</span> <span class="n">CrudFactory</span><span class="p">(</span> <div class="language-python highlight"><pre><span></span><code><span id="__span-40-1"><a id="__codelineno-40-1" name="__codelineno-40-1" href="#__codelineno-40-1"></a><span class="n">PostCrud</span> <span class="o">=</span> <span class="n">CrudFactory</span><span class="p">(</span>
</span><span id="__span-32-2"><a id="__codelineno-32-2" name="__codelineno-32-2" href="#__codelineno-32-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">Post</span><span class="p">,</span> </span><span id="__span-40-2"><a id="__codelineno-40-2" name="__codelineno-40-2" href="#__codelineno-40-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">Post</span><span class="p">,</span>
</span><span id="__span-32-3"><a id="__codelineno-32-3" name="__codelineno-32-3" href="#__codelineno-32-3"></a> <span class="n">m2m_fields</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;tag_ids&quot;</span><span class="p">:</span> <span class="n">Post</span><span class="o">.</span><span class="n">tags</span><span class="p">},</span> </span><span id="__span-40-3"><a id="__codelineno-40-3" name="__codelineno-40-3" href="#__codelineno-40-3"></a> <span class="n">m2m_fields</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;tag_ids&quot;</span><span class="p">:</span> <span class="n">Post</span><span class="o">.</span><span class="n">tags</span><span class="p">},</span>
</span><span id="__span-32-4"><a id="__codelineno-32-4" name="__codelineno-32-4" href="#__codelineno-32-4"></a><span class="p">)</span> </span><span id="__span-40-4"><a id="__codelineno-40-4" name="__codelineno-40-4" href="#__codelineno-40-4"></a><span class="p">)</span>
</span><span id="__span-32-5"><a id="__codelineno-32-5" name="__codelineno-32-5" href="#__codelineno-32-5"></a> </span><span id="__span-40-5"><a id="__codelineno-40-5" name="__codelineno-40-5" href="#__codelineno-40-5"></a>
</span><span id="__span-32-6"><a id="__codelineno-32-6" name="__codelineno-32-6" href="#__codelineno-32-6"></a><span class="n">post</span> <span class="o">=</span> <span class="k">await</span> <span class="n">PostCrud</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="n">obj</span><span class="o">=</span><span class="n">PostCreateSchema</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s2">&quot;Hello&quot;</span><span class="p">,</span> <span class="n">tag_ids</span><span class="o">=</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]))</span> </span><span id="__span-40-6"><a id="__codelineno-40-6" name="__codelineno-40-6" href="#__codelineno-40-6"></a><span class="n">post</span> <span class="o">=</span> <span class="k">await</span> <span class="n">PostCrud</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="n">obj</span><span class="o">=</span><span class="n">PostCreateSchema</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s2">&quot;Hello&quot;</span><span class="p">,</span> <span class="n">tag_ids</span><span class="o">=</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]))</span>
</span></code></pre></div> </span></code></pre></div>
<h2 id="upsert">Upsert<a class="headerlink" href="#upsert" title="Permanent link">&para;</a></h2> <h2 id="upsert">Upsert<a class="headerlink" href="#upsert" title="Permanent link">&para;</a></h2>
<p>Atomic <code>INSERT ... ON CONFLICT DO UPDATE</code> using PostgreSQL:</p> <p>Atomic <code>INSERT ... ON CONFLICT DO UPDATE</code> using PostgreSQL:</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-33-1"><a id="__codelineno-33-1" name="__codelineno-33-1" href="#__codelineno-33-1"></a><span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">upsert</span><span class="p">(</span> <div class="language-python highlight"><pre><span></span><code><span id="__span-41-1"><a id="__codelineno-41-1" name="__codelineno-41-1" href="#__codelineno-41-1"></a><span class="k">await</span> <span class="n">UserCrud</span><span class="o">.</span><span class="n">upsert</span><span class="p">(</span>
</span><span id="__span-33-2"><a id="__codelineno-33-2" name="__codelineno-33-2" href="#__codelineno-33-2"></a> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> </span><span id="__span-41-2"><a id="__codelineno-41-2" name="__codelineno-41-2" href="#__codelineno-41-2"></a> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span>
</span><span id="__span-33-3"><a id="__codelineno-33-3" name="__codelineno-33-3" href="#__codelineno-33-3"></a> <span class="n">obj</span><span class="o">=</span><span class="n">UserCreateSchema</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s2">&quot;alice@example.com&quot;</span><span class="p">,</span> <span class="n">username</span><span class="o">=</span><span class="s2">&quot;alice&quot;</span><span class="p">),</span> </span><span id="__span-41-3"><a id="__codelineno-41-3" name="__codelineno-41-3" href="#__codelineno-41-3"></a> <span class="n">obj</span><span class="o">=</span><span class="n">UserCreateSchema</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s2">&quot;alice@example.com&quot;</span><span class="p">,</span> <span class="n">username</span><span class="o">=</span><span class="s2">&quot;alice&quot;</span><span class="p">),</span>
</span><span id="__span-33-4"><a id="__codelineno-33-4" name="__codelineno-33-4" href="#__codelineno-33-4"></a> <span class="n">index_elements</span><span class="o">=</span><span class="p">[</span><span class="n">User</span><span class="o">.</span><span class="n">email</span><span class="p">],</span> </span><span id="__span-41-4"><a id="__codelineno-41-4" name="__codelineno-41-4" href="#__codelineno-41-4"></a> <span class="n">index_elements</span><span class="o">=</span><span class="p">[</span><span class="n">User</span><span class="o">.</span><span class="n">email</span><span class="p">],</span>
</span><span id="__span-33-5"><a id="__codelineno-33-5" name="__codelineno-33-5" href="#__codelineno-33-5"></a> <span class="n">set_</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;username&quot;</span><span class="p">},</span> </span><span id="__span-41-5"><a id="__codelineno-41-5" name="__codelineno-41-5" href="#__codelineno-41-5"></a> <span class="n">set_</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;username&quot;</span><span class="p">},</span>
</span><span id="__span-33-6"><a id="__codelineno-33-6" name="__codelineno-33-6" href="#__codelineno-33-6"></a><span class="p">)</span> </span><span id="__span-41-6"><a id="__codelineno-41-6" name="__codelineno-41-6" href="#__codelineno-41-6"></a><span class="p">)</span>
</span></code></pre></div> </span></code></pre></div>
<h2 id="response-serialization">Response serialization<a class="headerlink" href="#response-serialization" title="Permanent link">&para;</a></h2> <h2 id="response-serialization">Response serialization<a class="headerlink" href="#response-serialization" title="Permanent link">&para;</a></h2>
<div class="admonition info"> <div class="admonition info">
<p class="admonition-title">Added in <code>v1.1</code></p> <p class="admonition-title">Added in <code>v1.1</code></p>
</div> </div>
<p>Pass a Pydantic schema class to <code>create</code>, <code>get</code>, <code>update</code>, or <code>offset_paginate</code> to serialize the result directly into that schema and wrap it in a <a href="../../reference/schemas/#fastapi_toolsets.schemas.Response"><code>Response[schema]</code></a> or <a href="../../reference/schemas/#fastapi_toolsets.schemas.PaginatedResponse"><code>PaginatedResponse[schema]</code></a>:</p> <p>Pass a Pydantic schema class to <code>create</code>, <code>get</code>, <code>update</code>, or <code>offset_paginate</code> to serialize the result directly into that schema and wrap it in a <a href="../../reference/schemas/#fastapi_toolsets.schemas.Response"><code>Response[schema]</code></a> or <a href="../../reference/schemas/#fastapi_toolsets.schemas.PaginatedResponse"><code>PaginatedResponse[schema]</code></a>:</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-34-1"><a id="__codelineno-34-1" name="__codelineno-34-1" href="#__codelineno-34-1"></a><span class="k">class</span><span class="w"> </span><span class="nc">UserRead</span><span class="p">(</span><span class="n">PydanticBase</span><span class="p">):</span> <div class="language-python highlight"><pre><span></span><code><span id="__span-42-1"><a id="__codelineno-42-1" name="__codelineno-42-1" href="#__codelineno-42-1"></a><span class="k">class</span><span class="w"> </span><span class="nc">UserRead</span><span class="p">(</span><span class="n">PydanticBase</span><span class="p">):</span>
</span><span id="__span-34-2"><a id="__codelineno-34-2" name="__codelineno-34-2" href="#__codelineno-34-2"></a> <span class="nb">id</span><span class="p">:</span> <span class="n">UUID</span> </span><span id="__span-42-2"><a id="__codelineno-42-2" name="__codelineno-42-2" href="#__codelineno-42-2"></a> <span class="nb">id</span><span class="p">:</span> <span class="n">UUID</span>
</span><span id="__span-34-3"><a id="__codelineno-34-3" name="__codelineno-34-3" href="#__codelineno-34-3"></a> <span class="n">username</span><span class="p">:</span> <span class="nb">str</span> </span><span id="__span-42-3"><a id="__codelineno-42-3" name="__codelineno-42-3" href="#__codelineno-42-3"></a> <span class="n">username</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-34-4"><a id="__codelineno-34-4" name="__codelineno-34-4" href="#__codelineno-34-4"></a> </span><span id="__span-42-4"><a id="__codelineno-42-4" name="__codelineno-42-4" href="#__codelineno-42-4"></a>
</span><span id="__span-34-5"><a id="__codelineno-34-5" name="__codelineno-34-5" href="#__codelineno-34-5"></a><span class="nd">@router</span><span class="o">.</span><span class="n">get</span><span class="p">(</span> </span><span id="__span-42-5"><a id="__codelineno-42-5" name="__codelineno-42-5" href="#__codelineno-42-5"></a><span class="nd">@router</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
</span><span id="__span-34-6"><a id="__codelineno-34-6" name="__codelineno-34-6" href="#__codelineno-34-6"></a> <span class="s2">&quot;/</span><span class="si">{uuid}</span><span class="s2">&quot;</span><span class="p">,</span> </span><span id="__span-42-6"><a id="__codelineno-42-6" name="__codelineno-42-6" href="#__codelineno-42-6"></a> <span class="s2">&quot;/</span><span class="si">{uuid}</span><span class="s2">&quot;</span><span class="p">,</span>
</span><span id="__span-34-7"><a id="__codelineno-34-7" name="__codelineno-34-7" href="#__codelineno-34-7"></a> <span class="n">responses</span><span class="o">=</span><span class="n">generate_error_responses</span><span class="p">(</span><span class="n">NotFoundError</span><span class="p">),</span> </span><span id="__span-42-7"><a id="__codelineno-42-7" name="__codelineno-42-7" href="#__codelineno-42-7"></a> <span class="n">responses</span><span class="o">=</span><span class="n">generate_error_responses</span><span class="p">(</span><span class="n">NotFoundError</span><span class="p">),</span>
</span><span id="__span-34-8"><a id="__codelineno-34-8" name="__codelineno-34-8" href="#__codelineno-34-8"></a><span class="p">)</span> </span><span id="__span-42-8"><a id="__codelineno-42-8" name="__codelineno-42-8" href="#__codelineno-42-8"></a><span class="p">)</span>
</span><span id="__span-34-9"><a id="__codelineno-34-9" name="__codelineno-34-9" href="#__codelineno-34-9"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_user</span><span class="p">(</span><span class="n">session</span><span class="p">:</span> <span class="n">SessionDep</span><span class="p">,</span> <span class="n">uuid</span><span class="p">:</span> <span class="n">UUID</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Response</span><span class="p">[</span><span class="n">UserRead</span><span class="p">]:</span> </span><span id="__span-42-9"><a id="__codelineno-42-9" name="__codelineno-42-9" href="#__codelineno-42-9"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_user</span><span class="p">(</span><span class="n">session</span><span class="p">:</span> <span class="n">SessionDep</span><span class="p">,</span> <span class="n">uuid</span><span class="p">:</span> <span class="n">UUID</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Response</span><span class="p">[</span><span class="n">UserRead</span><span class="p">]:</span>
</span><span id="__span-34-10"><a id="__codelineno-34-10" name="__codelineno-34-10" href="#__codelineno-34-10"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">crud</span><span class="o">.</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">get</span><span class="p">(</span> </span><span id="__span-42-10"><a id="__codelineno-42-10" name="__codelineno-42-10" href="#__codelineno-42-10"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">crud</span><span class="o">.</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
</span><span id="__span-34-11"><a id="__codelineno-34-11" name="__codelineno-34-11" href="#__codelineno-34-11"></a> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> </span><span id="__span-42-11"><a id="__codelineno-42-11" name="__codelineno-42-11" href="#__codelineno-42-11"></a> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span>
</span><span id="__span-34-12"><a id="__codelineno-34-12" name="__codelineno-34-12" href="#__codelineno-34-12"></a> <span class="n">filters</span><span class="o">=</span><span class="p">[</span><span class="n">User</span><span class="o">.</span><span class="n">id</span> <span class="o">==</span> <span class="n">uuid</span><span class="p">],</span> </span><span id="__span-42-12"><a id="__codelineno-42-12" name="__codelineno-42-12" href="#__codelineno-42-12"></a> <span class="n">filters</span><span class="o">=</span><span class="p">[</span><span class="n">User</span><span class="o">.</span><span class="n">id</span> <span class="o">==</span> <span class="n">uuid</span><span class="p">],</span>
</span><span id="__span-34-13"><a id="__codelineno-34-13" name="__codelineno-34-13" href="#__codelineno-34-13"></a> <span class="n">schema</span><span class="o">=</span><span class="n">UserRead</span><span class="p">,</span> </span><span id="__span-42-13"><a id="__codelineno-42-13" name="__codelineno-42-13" href="#__codelineno-42-13"></a> <span class="n">schema</span><span class="o">=</span><span class="n">UserRead</span><span class="p">,</span>
</span><span id="__span-34-14"><a id="__codelineno-34-14" name="__codelineno-34-14" href="#__codelineno-34-14"></a> <span class="p">)</span> </span><span id="__span-42-14"><a id="__codelineno-42-14" name="__codelineno-42-14" href="#__codelineno-42-14"></a> <span class="p">)</span>
</span><span id="__span-34-15"><a id="__codelineno-34-15" name="__codelineno-34-15" href="#__codelineno-34-15"></a> </span><span id="__span-42-15"><a id="__codelineno-42-15" name="__codelineno-42-15" href="#__codelineno-42-15"></a>
</span><span id="__span-34-16"><a id="__codelineno-34-16" name="__codelineno-34-16" href="#__codelineno-34-16"></a><span class="nd">@router</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span> </span><span id="__span-42-16"><a id="__codelineno-42-16" name="__codelineno-42-16" href="#__codelineno-42-16"></a><span class="nd">@router</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
</span><span id="__span-34-17"><a id="__codelineno-34-17" name="__codelineno-34-17" href="#__codelineno-34-17"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">list_users</span><span class="p">(</span> </span><span id="__span-42-17"><a id="__codelineno-42-17" name="__codelineno-42-17" href="#__codelineno-42-17"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">list_users</span><span class="p">(</span>
</span><span id="__span-34-18"><a id="__codelineno-34-18" name="__codelineno-34-18" href="#__codelineno-34-18"></a> <span class="n">session</span><span class="p">:</span> <span class="n">SessionDep</span><span class="p">,</span> </span><span id="__span-42-18"><a id="__codelineno-42-18" name="__codelineno-42-18" href="#__codelineno-42-18"></a> <span class="n">session</span><span class="p">:</span> <span class="n">SessionDep</span><span class="p">,</span>
</span><span id="__span-34-19"><a id="__codelineno-34-19" name="__codelineno-34-19" href="#__codelineno-34-19"></a> <span class="n">params</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span><span class="nb">dict</span><span class="p">,</span> <span class="n">Depends</span><span class="p">(</span><span class="n">crud</span><span class="o">.</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate_params</span><span class="p">())],</span> </span><span id="__span-42-19"><a id="__codelineno-42-19" name="__codelineno-42-19" href="#__codelineno-42-19"></a> <span class="n">params</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span><span class="nb">dict</span><span class="p">,</span> <span class="n">Depends</span><span class="p">(</span><span class="n">crud</span><span class="o">.</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate_params</span><span class="p">())],</span>
</span><span id="__span-34-20"><a id="__codelineno-34-20" name="__codelineno-34-20" href="#__codelineno-34-20"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">OffsetPaginatedResponse</span><span class="p">[</span><span class="n">UserRead</span><span class="p">]:</span> </span><span id="__span-42-20"><a id="__codelineno-42-20" name="__codelineno-42-20" href="#__codelineno-42-20"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">OffsetPaginatedResponse</span><span class="p">[</span><span class="n">UserRead</span><span class="p">]:</span>
</span><span id="__span-34-21"><a id="__codelineno-34-21" name="__codelineno-34-21" href="#__codelineno-34-21"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">crud</span><span class="o">.</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">UserRead</span><span class="p">)</span> </span><span id="__span-42-21"><a id="__codelineno-42-21" name="__codelineno-42-21" href="#__codelineno-42-21"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">crud</span><span class="o">.</span><span class="n">UserCrud</span><span class="o">.</span><span class="n">offset_paginate</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">UserRead</span><span class="p">)</span>
</span></code></pre></div> </span></code></pre></div>
<p>The schema must have <code>from_attributes=True</code> (or inherit from <a href="../../reference/schemas/#fastapi_toolsets.schemas.PydanticBase"><code>PydanticBase</code></a>) so it can be built from SQLAlchemy model instances.</p> <p>The schema must have <code>from_attributes=True</code> (or inherit from <a href="../../reference/schemas/#fastapi_toolsets.schemas.PydanticBase"><code>PydanticBase</code></a>) so it can be built from SQLAlchemy model instances.</p>
<hr /> <hr />

View File

@@ -2353,7 +2353,7 @@ the result is automatically wrapped in a <code>Response[schema]</code>.</p>
<h3 id="fastapi_toolsets.crud.factory.AsyncCrud.cursor_paginate" class="doc doc-heading"> <h3 id="fastapi_toolsets.crud.factory.AsyncCrud.cursor_paginate" class="doc doc-heading">
<code class="highlight language-python"><span class="n">cursor_paginate</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">cursor</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">filters</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">joins</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">outer_join</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">load_options</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">order_by</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">items_per_page</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">search</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">search_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">search_column</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">facet_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">filter_by</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">schema</span><span class="p">)</span></code> <code class="highlight language-python"><span class="n">cursor_paginate</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">cursor</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">filters</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">joins</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">outer_join</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">load_options</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">order_by</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">order_joins</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">items_per_page</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">search</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">search_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">search_column</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">order_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">facet_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">filter_by</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">schema</span><span class="p">)</span></code>
<span class="doc doc-labels"> <span class="doc doc-labels">
<small class="doc doc-label doc-label-async"><code>async</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small>
@@ -2563,6 +2563,22 @@ tables.</p>
<code>None</code> <code>None</code>
</td> </td>
</tr> </tr>
<tr class="doc-section-item">
<td>
<code>order_fields</code>
</td>
<td>
<code><a class="autorefs autorefs-external" title="collections.abc.Sequence" href="https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence">Sequence</a>[<span title="fastapi_toolsets.types.OrderFieldType">OrderFieldType</span>] | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Fields allowed for sorting (overrides class default).</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item"> <tr class="doc-section-item">
<td> <td>
<code>facet_fields</code> <code>facet_fields</code>
@@ -2790,7 +2806,7 @@ list → IN clause. Raises InvalidFacetFilterError for unknown keys.</p>
<code>order_fields</code> <code>order_fields</code>
</td> </td>
<td> <td>
<code><a class="autorefs autorefs-external" title="collections.abc.Sequence" href="https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence">Sequence</a>[<span title="sqlalchemy.orm.QueryableAttribute">QueryableAttribute</span>[<a class="autorefs autorefs-external" title="typing.Any" href="https://docs.python.org/3/library/typing.html#typing.Any">Any</a>]] | None</code> <code><a class="autorefs autorefs-external" title="collections.abc.Sequence" href="https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence">Sequence</a>[<span title="fastapi_toolsets.types.OrderFieldType">OrderFieldType</span>] | None</code>
</td> </td>
<td> <td>
<div class="doc-md-description"> <div class="doc-md-description">
@@ -3984,7 +4000,7 @@ the result is automatically wrapped in a <code>Response[schema]</code>.</p>
<h3 id="fastapi_toolsets.crud.factory.AsyncCrud.offset_paginate" class="doc doc-heading"> <h3 id="fastapi_toolsets.crud.factory.AsyncCrud.offset_paginate" class="doc doc-heading">
<code class="highlight language-python"><span class="n">offset_paginate</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">filters</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">joins</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">outer_join</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">load_options</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">order_by</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">page</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">items_per_page</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">include_total</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">search</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">search_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">search_column</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">facet_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">filter_by</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">schema</span><span class="p">)</span></code> <code class="highlight language-python"><span class="n">offset_paginate</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">filters</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">joins</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">outer_join</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">load_options</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">order_by</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">order_joins</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">page</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">items_per_page</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">include_total</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">search</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">search_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">search_column</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">order_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">facet_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">filter_by</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">schema</span><span class="p">)</span></code>
<span class="doc doc-labels"> <span class="doc doc-labels">
<small class="doc doc-label doc-label-async"><code>async</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small>
@@ -4208,6 +4224,22 @@ the result is automatically wrapped in a <code>Response[schema]</code>.</p>
<code>None</code> <code>None</code>
</td> </td>
</tr> </tr>
<tr class="doc-section-item">
<td>
<code>order_fields</code>
</td>
<td>
<code><a class="autorefs autorefs-external" title="collections.abc.Sequence" href="https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence">Sequence</a>[<span title="fastapi_toolsets.types.OrderFieldType">OrderFieldType</span>] | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Fields allowed for sorting (overrides class default).</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item"> <tr class="doc-section-item">
<td> <td>
<code>facet_fields</code> <code>facet_fields</code>
@@ -4451,7 +4483,7 @@ list → IN clause. Raises InvalidFacetFilterError for unknown keys.</p>
<code>order_fields</code> <code>order_fields</code>
</td> </td>
<td> <td>
<code><a class="autorefs autorefs-external" title="collections.abc.Sequence" href="https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence">Sequence</a>[<span title="sqlalchemy.orm.QueryableAttribute">QueryableAttribute</span>[<a class="autorefs autorefs-external" title="typing.Any" href="https://docs.python.org/3/library/typing.html#typing.Any">Any</a>]] | None</code> <code><a class="autorefs autorefs-external" title="collections.abc.Sequence" href="https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence">Sequence</a>[<span title="fastapi_toolsets.types.OrderFieldType">OrderFieldType</span>] | None</code>
</td> </td>
<td> <td>
<div class="doc-md-description"> <div class="doc-md-description">
@@ -4539,7 +4571,7 @@ list → IN clause. Raises InvalidFacetFilterError for unknown keys.</p>
<h3 id="fastapi_toolsets.crud.factory.AsyncCrud.paginate" class="doc doc-heading"> <h3 id="fastapi_toolsets.crud.factory.AsyncCrud.paginate" class="doc doc-heading">
<code class="highlight language-python"><span class="n">paginate</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">pagination_type</span><span class="o">=</span><span class="n">PaginationType</span><span class="o">.</span><span class="n">OFFSET</span><span class="p">,</span> <span class="n">filters</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">joins</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">outer_join</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">load_options</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">order_by</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">page</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">cursor</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">items_per_page</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">include_total</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">search</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">search_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">search_column</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">facet_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">filter_by</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">schema</span><span class="p">)</span></code> <code class="highlight language-python"><span class="n">paginate</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">pagination_type</span><span class="o">=</span><span class="n">PaginationType</span><span class="o">.</span><span class="n">OFFSET</span><span class="p">,</span> <span class="n">filters</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">joins</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">outer_join</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">load_options</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">order_by</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">order_joins</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">page</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">cursor</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">items_per_page</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">include_total</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">search</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">search_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">search_column</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">order_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">facet_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">filter_by</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">schema</span><span class="p">)</span></code>
<span class="doc doc-labels"> <span class="doc doc-labels">
<small class="doc doc-label doc-label-async"><code>async</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small>
@@ -4557,17 +4589,19 @@ list → IN clause. Raises InvalidFacetFilterError for unknown keys.</p>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="n">outer_join</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="n">outer_join</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="n">load_options</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">ExecutableOption</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="n">load_options</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">ExecutableOption</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> <span class="n">order_by</span><span class="p">:</span> <span class="n">OrderByClause</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> <span class="n">order_by</span><span class="p">:</span> <span class="n">OrderByClause</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-10"><a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> <span class="n">page</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-10"><a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> <span class="n">order_joins</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-11"><a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a> <span class="n">cursor</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-11"><a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a> <span class="n">page</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-12"><a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a> <span class="n">items_per_page</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-12"><a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a> <span class="n">cursor</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-13"><a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a> <span class="n">include_total</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-13"><a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a> <span class="n">items_per_page</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-14"><a id="__codelineno-0-14" name="__codelineno-0-14" href="#__codelineno-0-14"></a> <span class="n">search</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">SearchConfig</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-14"><a id="__codelineno-0-14" name="__codelineno-0-14" href="#__codelineno-0-14"></a> <span class="n">include_total</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-15"><a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a> <span class="n">search_fields</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">SearchFieldType</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-15"><a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a> <span class="n">search</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">SearchConfig</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-16"><a id="__codelineno-0-16" name="__codelineno-0-16" href="#__codelineno-0-16"></a> <span class="n">search_column</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-16"><a id="__codelineno-0-16" name="__codelineno-0-16" href="#__codelineno-0-16"></a> <span class="n">search_fields</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">SearchFieldType</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-17"><a id="__codelineno-0-17" name="__codelineno-0-17" href="#__codelineno-0-17"></a> <span class="n">facet_fields</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">FacetFieldType</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-17"><a id="__codelineno-0-17" name="__codelineno-0-17" href="#__codelineno-0-17"></a> <span class="n">search_column</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-18"><a id="__codelineno-0-18" name="__codelineno-0-18" href="#__codelineno-0-18"></a> <span class="n">filter_by</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="n">BaseModel</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-18"><a id="__codelineno-0-18" name="__codelineno-0-18" href="#__codelineno-0-18"></a> <span class="n">order_fields</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">OrderFieldType</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-19"><a id="__codelineno-0-19" name="__codelineno-0-19" href="#__codelineno-0-19"></a> <span class="n">schema</span><span class="p">:</span> <span class="nb">type</span><span class="p">[</span><span class="n">BaseModel</span><span class="p">],</span> </span><span id="__span-0-19"><a id="__codelineno-0-19" name="__codelineno-0-19" href="#__codelineno-0-19"></a> <span class="n">facet_fields</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">FacetFieldType</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-20"><a id="__codelineno-0-20" name="__codelineno-0-20" href="#__codelineno-0-20"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">OffsetPaginatedResponse</span><span class="p">[</span><span class="n">Any</span><span class="p">]</span> </span><span id="__span-0-20"><a id="__codelineno-0-20" name="__codelineno-0-20" href="#__codelineno-0-20"></a> <span class="n">filter_by</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="n">BaseModel</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-21"><a id="__codelineno-0-21" name="__codelineno-0-21" href="#__codelineno-0-21"></a> <span class="n">schema</span><span class="p">:</span> <span class="nb">type</span><span class="p">[</span><span class="n">BaseModel</span><span class="p">],</span>
</span><span id="__span-0-22"><a id="__codelineno-0-22" name="__codelineno-0-22" href="#__codelineno-0-22"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">OffsetPaginatedResponse</span><span class="p">[</span><span class="n">Any</span><span class="p">]</span>
</span></code></pre></div><div class="language-python doc-signature highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">paginate</span><span class="p">(</span> </span></code></pre></div><div class="language-python doc-signature highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">paginate</span><span class="p">(</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a> <span class="n">session</span><span class="p">:</span> <span class="n">AsyncSession</span><span class="p">,</span> </span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a> <span class="n">session</span><span class="p">:</span> <span class="n">AsyncSession</span><span class="p">,</span>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="o">*</span><span class="p">,</span> </span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="o">*</span><span class="p">,</span>
@@ -4577,17 +4611,19 @@ list → IN clause. Raises InvalidFacetFilterError for unknown keys.</p>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="n">outer_join</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="n">outer_join</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="n">load_options</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">ExecutableOption</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="n">load_options</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">ExecutableOption</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> <span class="n">order_by</span><span class="p">:</span> <span class="n">OrderByClause</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> <span class="n">order_by</span><span class="p">:</span> <span class="n">OrderByClause</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-10"><a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> <span class="n">page</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-10"><a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> <span class="n">order_joins</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-11"><a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a> <span class="n">cursor</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-11"><a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a> <span class="n">page</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-12"><a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a> <span class="n">items_per_page</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-12"><a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a> <span class="n">cursor</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-13"><a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a> <span class="n">include_total</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-13"><a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a> <span class="n">items_per_page</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-14"><a id="__codelineno-0-14" name="__codelineno-0-14" href="#__codelineno-0-14"></a> <span class="n">search</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">SearchConfig</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-14"><a id="__codelineno-0-14" name="__codelineno-0-14" href="#__codelineno-0-14"></a> <span class="n">include_total</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-15"><a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a> <span class="n">search_fields</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">SearchFieldType</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-15"><a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a> <span class="n">search</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">SearchConfig</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-16"><a id="__codelineno-0-16" name="__codelineno-0-16" href="#__codelineno-0-16"></a> <span class="n">search_column</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-16"><a id="__codelineno-0-16" name="__codelineno-0-16" href="#__codelineno-0-16"></a> <span class="n">search_fields</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">SearchFieldType</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-17"><a id="__codelineno-0-17" name="__codelineno-0-17" href="#__codelineno-0-17"></a> <span class="n">facet_fields</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">FacetFieldType</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-17"><a id="__codelineno-0-17" name="__codelineno-0-17" href="#__codelineno-0-17"></a> <span class="n">search_column</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-18"><a id="__codelineno-0-18" name="__codelineno-0-18" href="#__codelineno-0-18"></a> <span class="n">filter_by</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="n">BaseModel</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span> </span><span id="__span-0-18"><a id="__codelineno-0-18" name="__codelineno-0-18" href="#__codelineno-0-18"></a> <span class="n">order_fields</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">OrderFieldType</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-19"><a id="__codelineno-0-19" name="__codelineno-0-19" href="#__codelineno-0-19"></a> <span class="n">schema</span><span class="p">:</span> <span class="nb">type</span><span class="p">[</span><span class="n">BaseModel</span><span class="p">],</span> </span><span id="__span-0-19"><a id="__codelineno-0-19" name="__codelineno-0-19" href="#__codelineno-0-19"></a> <span class="n">facet_fields</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">FacetFieldType</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-20"><a id="__codelineno-0-20" name="__codelineno-0-20" href="#__codelineno-0-20"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">CursorPaginatedResponse</span><span class="p">[</span><span class="n">Any</span><span class="p">]</span> </span><span id="__span-0-20"><a id="__codelineno-0-20" name="__codelineno-0-20" href="#__codelineno-0-20"></a> <span class="n">filter_by</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="n">BaseModel</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="o">...</span><span class="p">,</span>
</span><span id="__span-0-21"><a id="__codelineno-0-21" name="__codelineno-0-21" href="#__codelineno-0-21"></a> <span class="n">schema</span><span class="p">:</span> <span class="nb">type</span><span class="p">[</span><span class="n">BaseModel</span><span class="p">],</span>
</span><span id="__span-0-22"><a id="__codelineno-0-22" name="__codelineno-0-22" href="#__codelineno-0-22"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">CursorPaginatedResponse</span><span class="p">[</span><span class="n">Any</span><span class="p">]</span>
</span></code></pre></div> </div> </span></code></pre></div> </div>
@@ -4843,6 +4879,22 @@ only applies when <code>pagination_type</code> is <code>OFFSET</code>.</p>
<code>None</code> <code>None</code>
</td> </td>
</tr> </tr>
<tr class="doc-section-item">
<td>
<code>order_fields</code>
</td>
<td>
<code><a class="autorefs autorefs-external" title="collections.abc.Sequence" href="https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence">Sequence</a>[<span title="fastapi_toolsets.types.OrderFieldType">OrderFieldType</span>] | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Fields allowed for sorting (overrides class default).</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item"> <tr class="doc-section-item">
<td> <td>
<code>facet_fields</code> <code>facet_fields</code>
@@ -5124,7 +5176,7 @@ field. Scalar → equality, list → IN clause. Raises
<code>order_fields</code> <code>order_fields</code>
</td> </td>
<td> <td>
<code><a class="autorefs autorefs-external" title="collections.abc.Sequence" href="https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence">Sequence</a>[<span title="sqlalchemy.orm.QueryableAttribute">QueryableAttribute</span>[<a class="autorefs autorefs-external" title="typing.Any" href="https://docs.python.org/3/library/typing.html#typing.Any">Any</a>]] | None</code> <code><a class="autorefs autorefs-external" title="collections.abc.Sequence" href="https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence">Sequence</a>[<span title="fastapi_toolsets.types.OrderFieldType">OrderFieldType</span>] | None</code>
</td> </td>
<td> <td>
<div class="doc-md-description"> <div class="doc-md-description">
@@ -5657,7 +5709,7 @@ responses. Supports direct columns (<code>User.status</code>) and relationship t
<code>order_fields</code> <code>order_fields</code>
</td> </td>
<td> <td>
<code><a class="autorefs autorefs-external" title="collections.abc.Sequence" href="https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence">Sequence</a>[<span title="sqlalchemy.orm.QueryableAttribute">QueryableAttribute</span>[<a class="autorefs autorefs-external" title="typing.Any" href="https://docs.python.org/3/library/typing.html#typing.Any">Any</a>]] | None</code> <code><a class="autorefs autorefs-external" title="collections.abc.Sequence" href="https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence">Sequence</a>[<span title="fastapi_toolsets.types.OrderFieldType">OrderFieldType</span>] | None</code>
</td> </td>
<td> <td>
<div class="doc-md-description"> <div class="doc-md-description">

File diff suppressed because one or more lines are too long