ox.core
Core application libraries.
ox.core.apps
Oxylus application inherits from AppConfig. It allows to:
handle assets;
provide application metadata;
application level permission;
We plan to use those metadata and dependencies in order to automate loading and ease application installation by end-users.
- class ox.core.apps.AppConfig(*args, **kwargs)[source]
Base AppConfig application to use for Oxylus applications.
It provides extra features as:
It is planned later to handle app dependencies.
-
assets:
Assets= <ox.assets.base.Assets object> The assets use by the application. It will be used at two places:
building and managing assets, through
./manage.py assets;rendering scripts and stylesheets includes into templates
Note: there is no need to provide an extra
Assetspecifying the application to be compiled, since it is what the Assets class does.
-
dependencies:
list[Type[AppConfig]] |None= None List of required dependencies for this application.
-
icon:
str= 'mdi-home' Material design icon class.
-
npm_package:
str|None= None Name of the corresponding NPM package to look up for.
Defaults to app label.
-
root_url:
str= '' Provide an alternative to app label when we target application in paths.
For example Oxylus will nest template directories as
ox/core/instead ofox_core. The same happens for urls.
-
assets:
- class ox.core.apps.AppMeta[source]
-
dependencies:
tuple[str] = () Application dependencies, as a tuple of:
AppConfig_name: related app config
TODO: (AppConfig_name, “version”): where `version is matched agains’t “^” operator.
-
description:
str= '' Describe application here.
Default will be fetched from metadatas.
-
extra_metadata:
dict[str,str] |None= None Application metadata.
If not provided, fetch those information based on root module of the package (using
importlib.metadatay).
-
permission:
str= '' Permission to access application.
-
dependencies:
- class ox.core.apps.CoreAppConfig(*args, **kwargs)[source]
-
icon:
str= 'mdi-weather-sunny' Material design icon class.
-
npm_package:
str|None= '@oxylus/core' Name of the corresponding NPM package to look up for.
Defaults to app label.
-
root_url:
str= 'ox/core' Provide an alternative to app label when we target application in paths.
For example Oxylus will nest template directories as
ox/core/instead ofox_core. The same happens for urls.
-
icon:
ox.core.exceptions
ox.core.models
- class ox.core.models.InheritanceQuerySet(*args, **kwargs)[source]
This is utility QuerySet subclass for
Model, inheriting frommodel_utils.InheritanceQuerySet.
- class ox.core.models.Model(*args, **kwargs)[source]
Model class used by Oxylus applications. It provides:
public uuid: reducing bruteforcing database row index;
url reverse;
Using
uuidas a public identifier is preferred over directly exposing database primary key.- classmethod reverse_url(action, namespace='', **kwargs)[source]
Reverse an url for the provided action.
- Return type:
str- Parameters:
action (str) – name of the action (eg. detail, update);
namespace (str) – if provided insert namespace after application namespace;
**kwargs –
passed down to reverse
:return reversed url as string.
ox.core.panels
This module provide application’s panels description.
This is used to generate main navigation menu and application view’s panels.
Panels are logically organised using the following structure:
Panels are defined in applications’ module panels.py in order to separate concerns with the views. However
they are not discovered automatically, but by importing the module into the view (in order to assign panels).
Panel and panels are registered through the global object registry.
Application template
An AppView have panels assigned to a Panels
instance. This is used to generate components inside the template using
provided Panel.component (aka Vue component), and Panel.template, actions_template
(used for extensibility).
Example
By convention the navigation items are registered inside panels.py module, such as:
from ox.core.panels import registry, Panel, Panels panels = Panels("contacts", _("Contacts"), items=[ Panel("persons", _("Persons"), "mdi-card-account-mail", url="ox_contacts:index", order=0, permission="ox_contacts.view_person", ), # ... Panels("settings", _("Settings"), order=100, items=[ Panel("organisationtypes", _("Organisation Types"), "mdi-domain-switch", url="ox_contacts:index", permission="ox_contacts.view_organisationtype", ) ], ), ]) ) registry.append(panels) # use this to append to an already registered group: # registry["settings"].append(panels)
- class ox.core.panels.Panel(name, title, icon='', component='', **kwargs)[source]
Describe a panel component and its navigation.
-
component:
str= '' Vue component.
- template = 'ox/core/components/model_panel.html'
Django template file used to render the panel
-
type:
str= 'item' Menu item type:
group,subheader,item.Use by frontend
OxNavItem.
-
url:
str= None Url name to app view. It MUST always be namespaced under app’s name.
-
component:
- class ox.core.panels.Panels(name, title, items=None, **kwargs)[source]
Regroup multiple panels, usually of an application.
This also can be used in a more UX sense of the term, such as “Settings” would regroup different nested application Panels.
-
type:
str= 'group' Menu item type:
group,subheader,item.Use by frontend
OxNavItem.
-
type:
- class ox.core.panels.Registry(items=None)[source]
Register all applications’ panels.
The following registry methods reset the cached property
nav_data():append(),__getitem__(),__setitem__(). Those are the public methods used to update the registry, whilstnav_datais used to provide navigation data to the user and is cached for performance.- append(item)[source]
Add new item to group.
- Parameters:
item – item
path – dot separated path to parent group
- Returns:
the appended item
Menu data as provided to frontend application.
- ox.core.panels.registry = <ox.core.panels.Registry object>
Registry of all applications’ panels.
ox.core.renderers
ox.core.signals
ox.core.serializers
- class ox.core.serializers.ModelSerializer(*args, **kwargs)[source]
This ModelSerializer provides
idfield defaulted to model’s uuid.
- class ox.core.serializers.NestedSerializer(*args, **kwargs)[source]
This serializer class allows to specify and save relations using nested serializer values.
Default behavior implies that existing values will be updated, new ones created and removed one deleted. You can customize by provided argument for the
NestedInfospecific to a field.The attribute
Meta.nestedis used to specify which fields are actually related models. Its value is a list of:a string that is
NestedInfo.field(serializer field name);tuple with positional argument, dict with positional arguments;
a
NestedInfoinstance;
Limitations: - It only works with models having a
uuidfield used as reference. - It assumes a FK reverse relations.Example: two models, A and B. B has ForeignKey to A, and on A’s serializer you want to update B objects related to A. You don’t want uuid as handled by
RelatedField).class BSerializer(ModelSerializer): # ... class ASerializer(ModelSerializer): b_items = BSerializer(source="b_set", many=True, required=False) class Meta: # Declaring fields as nested allows them to be automatically # create/updated. nested = ("b_items",) # ... # # If you dont want deletion of missing items, you can use this: # nested = (("b_items", False),)
At the serializer class creation,
Meta.nestedis transformed into a dict ofNestedInfoby serializer field name.- create(validated_data)[source]
We have a bit of extra checking around this in order to provide descriptive messages when something goes wrong, but this method is essentially just:
return ExampleModel.objects.create(**validated_data)
If there are many to many fields present on the instance then they cannot be set until the model is instantiated, in which case the implementation is like so:
example_relationship = validated_data.pop(‘example_relationship’) instance = ExampleModel.objects.create(**validated_data) instance.example_relationship = example_relationship return instance
The default implementation also does not handle nested relationships. If you want to support writable nested relationships you’ll need to write an explicit .create() method.
ox.core.views
ox.core.views.accounts
- class ox.core.views.accounts.AccountView(**kwargs)[source]
- app_config_name: str | None = 'ox_core'
AppConfig name of the related application.
If none provided, retrieve it based of request’s resolver match.
- title: str = 'My Account'
Application title (as displayed in
<title>and top bar).
ox.core.views.api
ox.core.views.auth
- class ox.core.views.auth.ContentTypeViewSet(**kwargs)[source]
- serializer_class
alias of
ContentTypeSerializer