Generate Qt-related classes content using DRF from sqlalchemy models.
Project description
exdrf-gen-al2qt
exdrf-gen-al2qt is an exdrf-gen plugin that generates PyQt5 UI and
model scaffolding from an ExDataset derived from SQLAlchemy declarative
models. generate_qt_from_alchemy walks a deep template tree (menus,
plugins, routers, per-category and per-resource widgets, editors, lists,
selectors, field classes, and HTML viewers). Runtime code depends on
exdrf-qt.
Python 3.12.2+ is required.
Dependencies
PyQt5(declared inpyproject.toml)exdrf-gen,exdrf-al, andclick- The
exdrf_qtlibrary (generated code andcreatorimport this package for field base classes, widgets, plugins, and routing)
Command-line usage
exdrf-gen al2qt DATASET OUT-PATH OUT-MODULE DB-MODULE
Or: python -m exdrf_gen al2qt ... with the same arguments.
- DATASET —
module.path:Symbolfor the SQLAlchemy declarative base (GetDatasetinexdrf_al.click_support). - OUT-PATH — output directory. Env:
EXDRF_AL2QT_PATH. - OUT-MODULE — Python package name for generated code.
- DB-MODULE — module where SQLAlchemy models are defined.
Root group options: --debug, --version.
Python API
from exdrf_gen.jinja_support import jinja_env
from exdrf_gen_al2qt.creator import generate_qt_from_alchemy
generate_qt_from_alchemy(
d_set=dataset,
out_path="/path/to/out",
out_module="my_app.qt_gen",
db_module="my_app.db.models",
env=jinja_env,
)
Templates and regeneration
Jinja sources live under exdrf_gen_al2qt/al2qt_templates/. Regenerated
files support preserve regions (exdrf-keep-start / exdrf-keep-end) as
described in exdrf-gen’s fs_support documentation; see also
Preserving custom content at the end of this file.
Plugin registration
[project.entry-points.'exdrf.plugins']
exdrf_gen = 'exdrf_gen_al2qt'
See also
exdrf-gen—README.md(plugins, Jinja globals,fs_support)
Template variables reference
This section documents all the variables available to different template types
used by generate_qt_from_alchemy. Templates are organized into four levels:
top-level, category-level, resource-level, and field-level. Each level has
access to its own specific variables plus all variables from parent levels.
Common Variables Available to All Templates
These variables are available in every template regardless of its level:
-
source_module: The name of the Python module where the generator function is defined. This is typically used in generated file headers to indicate the source. -
source_templ: The path to the template file being used to generate the output. This helps identify which template was used when reading generated files. -
dset: The dataset object (ExDataset) that contains all resources and their relationships. You can access any resource usingdset[resource_name]. -
out_module: The module name where generated files will be placed. This is the value passed togenerate_qt_from_alchemyas theout_moduleparameter. -
db_module: The module name where the SQLAlchemy database models are defined. This is the value passed togenerate_qt_from_alchemyas thedb_moduleparameter. -
env: The Jinja2 template environment used for rendering templates.
Preserved Content Variables
These variables are automatically preserved when regenerating files. Content between special comment markers in existing files is preserved and made available to templates:
-
other_imports: Preserved import statements that should be kept in generated files. -
other_globals: Preserved global variable definitions. -
other_attributes: Preserved class attributes (varies by template type). -
more_content: General preserved content at the end of files. -
Template-specific preserved content variables (e.g.,
extra_init,extra_editor_content,extra_field_content, etc.) are documented in their respective template sections.
1. Top-Level Templates
Top-level templates generate files at the root of the output directory. They have access to all common variables plus the dataset-level variables below.
Template Files
menus.py.j2: Generates menu actions and menus for all resourcesplugins.py.j2: Generates plugin hook definitions for all resourcesrouter.py.j2: Generates routing configuration for navigation between resources__init__.py.j2: Generates an empty__init__.pyfile with preserved content
Available Variables
-
categ_map: A dictionary mapping category names to their resources. Each key is a category name (string), and each value is a list of resource names belonging to that category. -
categ_zero: An iterator that yields tuples of (category_name, resources_list) for all categories in the dataset. Useful for iterating through categories. -
resources: A list of all resource objects (ExResource) in the dataset. -
resources_sd: Resources sorted by their dependencies. Resources that depend on others appear after them in this list. -
sorted_resources_for_ui(dset, resource_list): A function that sorts resources for UI display. By default, it sorts alphabetically, but can be customized via thesr_for_uiparameter.
2. Category-Level Templates
Category-level templates generate files within category directories. They have access to all common variables, all top-level variables, plus the category-specific variables below.
Category Template Files
-
c/api.py.j2: Generates the API module that exports all widgets and models for resources in this category -
c/__init__.py.j2: Generates an__init__.pyfile for the category module
Available Variables for Category Template Files
-
category_snake: The category name in snake_case format (lowercase with underscores). This is used for directory and module names. -
resources: A list of all resource objects (ExResource) that belong to this specific category.
3. Resource-Level Templates
Resource-level templates generate files for individual resources (models). They have access to all common variables, all top-level variables, all category-level variables, plus the resource-specific variables below.
Resource Template Files
-
c/m/api.py.j2: Generates the API module that exports all widgets and models for this specific resource -
c/m/m_ful.py.j2: Generates the full model class that contains all fields of the resource for table/list displays -
c/m/m_ocm.py.j2: Generates the name-only model class that contains only the label field, suitable for selectors and comboboxes -
c/m/single_f.py.j2: Generates a special label field class that provides a human-readable label for the entire record -
c/m/w/editor.py.j2: Generates the editor widget class that allows users to create and edit records -
c/m/w/editor.ui.j2: Generates the Qt UI file (XML) that defines the visual layout of the editor widget -
c/m/w/list.py.j2: Generates the list widget class that displays a table of records -
c/m/w/selector.py.j2: Generates single-select and multi-select widget classes for choosing records -
c/m/w/templ_viewer.py.j2: Generates a template-based viewer widget for displaying records using HTML templates -
c/m/w/view_templ.html.j2: Generates an HTML template for displaying records in the template viewer -
c/m/__init__.py.j2: Generates an__init__.pyfile for the resource module
Available Variables for Resource Template Files
Resource Object Variables
-
r: The resource object (ExResource) itself. This provides access to all properties and methods of the resource. -
ResPascal: The resource name in PascalCase format (e.g., "UserProfile" from "user_profile"). Used for class names. -
res_snake: The resource name in snake_case format (e.g., "user_profile"). Used for file names and variable names. -
res_p_snake: The plural form of the resource name in snake_case (e.g., "user_profiles"). Used for directory names. -
res_camel: The resource name in camelCase format (e.g., "userProfile"). Used in some variable names. -
res_text: A human-readable text name for the resource, typically used in UI labels. -
ResText: The capitalized version ofres_text, used in titles. -
res_docs: The docstring of the resource split into lines. This contains the description of what the resource represents. -
categories: A list of category names (strings) that this resource belongs to. Categories represent nested module paths.
Resource Field Information
-
fields: A list of all field objects (ExField) belonging to this resource, sorted using the resource's field sorting method. -
fields_cats: A dictionary mapping category names to lists of fields. Fields can be organized into categories for better UI organization (tabs in editors, sections in forms).
Resource Primary Key Information
-
res_mfs: The minimum field set - a list of fields that uniquely identify a record when combined. This typically includes the primary key fields. -
res_spl_id: A boolean indicating whether the resource has a simple (single-field) primary key. True means one field, False means multiple fields form a composite key. -
res_primaries: A list of field names that form the primary key. For simple primary keys, this contains one name; for composite keys, it contains multiple names.
Resource Relationship Information
-
all_related_models: A list of all resource objects that are related to this resource through foreign key relationships. These are resources that can be loaded together for efficient database queries. -
all_related_paths: A list of relationship paths (SQLAlchemy query options) that specify how to load related resources. These are used in database queries to eagerly load related data. -
all_related_label_models: Similar toall_related_models, but only includes resources needed for generating record labels (human-readable identifiers). -
all_related_label_paths: Similar toall_related_paths, but only includes paths needed for label generation.
Resource Functions
-
sorted_fields_for_ui(dset, resource, fields_list): A function that sorts fields for UI display. By default, it returns fields in their defined order, but can be customized via thesf_for_uiparameter. -
read_only_fields: A dictionary that defines which fields should be read-only in editors. Keys can be:- Field name only:
"field_name"(applies to this field across all resources) - Resource-qualified:
"resource_name.field_name"(applies only to this specific resource's field)
Values are dictionaries with optional keys:
"rec_to_str": A Python format string used to populate the editor widget. It receives afieldargument with the field name. Default generatesself.c_{field}.setText(str(record.{field}) if record else "")."ui_xml": XML content for the field widget in the UI file. Default creates a read-only QLineEdit.
- Field name only:
Resource Methods (via r object)
-
r.sorted_fields: Returns fields sorted according to the resource's sorting logic. -
r.sorted_fields_and_categories(): Returns a dictionary mapping category names to sorted lists of fields in that category. -
r.primary_fields(): Returns a list of field names that form the primary key. -
r.primary_inst_fields(): Returns the actual field objects (not just names) that form the primary key. -
r.label_to_python(): Returns Python code (as a string) that generates the human-readable label for a record. This is typically used in label field implementations. -
r[name]: Allows accessing fields by name using dictionary-style syntax. Returns the field object or raises KeyError if not found. -
r.is_connection_resource: A boolean property indicating if this resource represents a database connection configuration. -
r.minimum_field_set: Returns the minimum set of fields needed to construct the label of a record (in principle, it should be able to uniquely identify a record, but that constraint is not enforced).
4. Field-Level Templates
Field-level templates generate files for individual fields within a resource. They have access to all common variables, all top-level variables, all category-level variables, all resource-level variables, plus the field-specific variables below.
Field Template Files
c/m/field.py.j2: Generates the field definition class that specifies how the field is displayed, filtered, and edited in the UI
Available Variables for Field Template Files
Field Object Variables
-
field: The field object (ExField) itself. This provides access to all properties and methods of the field. -
FldPascal: The field name in PascalCase format (e.g., "FirstName" from "first_name"). Used for class names. -
fld_snake: The field name in snake_case format (e.g., "first_name"). Used for file names and variable names. -
fld_p_snake: The plural form of the field name in snake_case. Used in some contexts where pluralization is needed. -
fld_camel: The field name in camelCase format (e.g., "firstName"). Used in some variable names. -
fld_text: A human-readable text name for the field, typically used in UI labels. -
FldText: The capitalized version offld_text, used in titles. -
fld_docs: The docstring of the field split into lines. This contains the description of what the field represents. -
fld_bc: The base class name for the field type in PascalCase format (e.g., "RefManyToOne", "String", "Integer"). This is derived from the field type name. -
fld_attrs: A dictionary containing all attribute values of the field object. Keys are attribute names, values are their current values. This is used to determine which field attributes differ from their defaults. -
fld_is_ref: A boolean indicating whether this field is a reference field (foreign key or relationship field). True for one-to-one, one-to-many, many-to-one, and many-to-many relationships.
Field Functions
-
gfp(field, fld_attrs, fld_bc): A function that generates field parts- it returns a generator yielding tuples of
(attribute_name, type_name, default_value_string)for all field attributes that differ from their base class defaults. Used to generate only the custom attributes in field class definitions.
- it returns a generator yielding tuples of
-
base_ui_class(field): A function that returns the Qt widget class name that should be used for editing this field. By default, it maps field types to widget classes (e.g., "string" → "DrfLineEditor", "integer" → "DrfIntEditor", "many-to-one" → "Qt{ResourceName}SiSe"). Can be customized via thebase_ui_classparameter.
Field Methods (via field object)
-
field.type_name: The type name of the field as a string (e.g., "string", "integer", "date", "many-to-one", "one-to-many"). -
field.name: The name of the field as defined in the database model. -
field.title: The human-readable title/label for the field. -
field.description: The full description text of the field (if available). -
field.doc_lines: The description split into lines (list of strings). -
field.primary: Boolean indicating if this field is part of the primary key. -
field.nullable: Boolean indicating if this field can have NULL/None values. -
field.read_only: Boolean indicating if this field should be read-only in editors. -
field.category: The category name that this field belongs to (for UI organization). -
field.fk_to: If this is a foreign key field, this is the resource object that this field references. None otherwise. -
field.fk_from: If this field is referenced by other resources, this property provides information about those references. -
field.ref: For reference fields, this is the resource object that the field references. -
field.enum_values: For enum fields, this is a list of tuples representing (value, label) pairs for the enum options. -
field.multiline: For string fields, this boolean indicates if the field should use a multi-line text editor. -
field.is_ref_type: Boolean indicating if this is a reference relationship field. -
field.is_many_to_many_type: Boolean indicating if this is a many-to-many relationship. -
field.is_one_to_many_type: Boolean indicating if this is a one-to-many relationship. -
field.ref.pascal_case_name: Whenfield.refexists, this is the PascalCase name of the referenced resource. -
field.ref.categories: Whenfield.refexists, this is the list of categories that the referenced resource belongs to. -
field.ref.snake_case_name_plural: Whenfield.refexists, this is the plural snake_case name of the referenced resource. -
field.ref.primary_fields(): Whenfield.refexists, this method returns the primary key field names of the referenced resource. -
field.ref.is_primary_simple: Whenfield.refexists, this boolean indicates if the referenced resource has a simple (single-field) primary key. -
field.ref.label_to_python(): Whenfield.refexists, this method returns Python code that generates the label for records of the referenced resource. -
field.ref.get_fields_for_ref_filtering(): Whenfield.refexists, this method returns a list of fields that should be used for filtering and searching when selecting referenced records.
Field-Specific Functions for Editor UI Template
enum_v2p(enum_values): A function that converts enum values (list of tuples) to a property string format. Takes enum values like[(1, "Option 1"), (2, "Option 2")]and converts them to"1:Option 1,2:Option 2"for use in Qt widget properties.
Template Usage Examples
Example 1: Using Resource Variables
In a resource-level template, you can access resource information like this:
The resource {{ ResPascal }} ({{ res_snake }}) belongs to
{{ categories|join(', ') }} categories and has {{ fields|length }} fields.
Example 2: Iterating Through Fields
{% for field in fields %}
Field {{ field.name }} is of type {{ field.type_name }}
{% endfor %}
Example 3: Conditional Logic Based on Primary Key
{% if res_spl_id %}
return record.{{ res_primaries[0] }}
{% else %}
return ({{ res_primaries|join(', record.') }})
{% endif %}
Example 4: Generating Code with Field Attributes
{% for part_name, part_class, part_default in gfp(field, fld_attrs, fld_bc) %}
{{ part_name }}: {{ part_class }} = field(default={{ part_default }})
{% endfor %}
Preserving Custom Content
When templates are regenerated, content between special comment markers is preserved. Place your custom code between these markers:
# exdrf-keep-start variable_name ----------------------------------------------
Your custom code here
# exdrf-keep-end variable_name ------------------------------------------------
The variable_name should match one of the preserved content variables
documented above. For example, to add custom imports, use:
# exdrf-keep-start other_imports ----------------------------------------------
from my_custom_module import MyClass
# exdrf-keep-end other_imports -------------------------------------------------
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file exdrf_gen_al2qt-0.1.15.tar.gz.
File metadata
- Download URL: exdrf_gen_al2qt-0.1.15.tar.gz
- Upload date:
- Size: 23.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df2706c5e4153dd115d1f8952de019a19c8f8241a00f52ede2064825b77efd0a
|
|
| MD5 |
1a058b5bd5a9d663fe60bef3c75898e5
|
|
| BLAKE2b-256 |
cd8bec894b531de79b80e7296ddb5ba700c3e399bee51049e169ec54500c9d18
|
File details
Details for the file exdrf_gen_al2qt-0.1.15-py3-none-any.whl.
File metadata
- Download URL: exdrf_gen_al2qt-0.1.15-py3-none-any.whl
- Upload date:
- Size: 16.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46e1cf54d828a180baf67ce914bd2efacfa54cabae57634a4053204489968f04
|
|
| MD5 |
b4c038e9579d7aa62ce008dca2d6c0b8
|
|
| BLAKE2b-256 |
ad13120bd583b012ddb58e00a73d1cd311fe43b9e048201e88d430aec1ef8657
|