apis_core.relations package

Subpackages

Submodules

apis_core.relations.admin module

apis_core.relations.apps module

class apis_core.relations.apps.RelationsNgConfig(app_name, app_module)[source]

Bases: AppConfig

default_auto_field = 'django.db.models.AutoField'
name = 'apis_core.relations'
ready()[source]

Override this method in subclasses to run code when Django starts.

apis_core.relations.filtersets module

class apis_core.relations.filtersets.EntityFilter(*args, **kwargs)[source]

Bases: CharFilter

Custom CharFilter that uses the generate_search_filter helper to search in all instances inheriting from RootObject and then uses those results to only list relations that point to one of the results.

filter(qs, value)[source]
class apis_core.relations.filtersets.RelationFilterSet(*args, **kwargs)[source]

Bases: GenericFilterSet

Override the GenericFilterSet that is created for the Relation model. It does not really make sense to filter for content type id and object id, so we exclude those. Instead, we add a multiple choice filter for object and subject class, that only lists those choices that actually exists (meaning the classes that are actually set as subj or obj in some relation). Additionaly, we add a search filter, that searches in instances connected to relations (this does only work for instances inheriting from RootObject).

class Meta[source]

Bases: object

exclude = ['subj_object_id', 'subj_content_type', 'obj_object_id', 'obj_content_type']
form

alias of GenericFilterSetForm

base_filters = {'obj_search': <apis_core.relations.filtersets.EntityFilter object>, 'subj_search': <apis_core.relations.filtersets.EntityFilter object>}
declared_filters = {'obj_search': <apis_core.relations.filtersets.EntityFilter object>, 'subj_search': <apis_core.relations.filtersets.EntityFilter object>}
class apis_core.relations.filtersets.SubjObjClassFilter(models, *args, **kwargs)[source]

Bases: MultipleChoiceFilter

Custom MultipleChoiceFilter * it lists model classes as choices, that are in some way

connected to a relation, either as subj or as obj

  • it filters relations by the content types of the connected subjects and objects

filter(qs, value: list[str] | None)[source]

apis_core.relations.forms module

class apis_core.relations.forms.CustomSelect2ListChoiceField(choice_list=None, required=True, widget=None, label=None, initial=None, help_text='', *args, **kwargs)[source]

Bases: Select2ListChoiceField

We use a custom Select2ListChoiceField in our Relation form, because we don’t want the form value to be validated. The field uses the choices setting as a basis for validating, but our choices span over multiple querysets, so its easier to simply not validate (some validation happens in the clean method anyway).

Use a list to generate choices in a ChoiceField.

function that returns a list.

validate(value)[source]

Validate that the input is in self.choices.

class apis_core.relations.forms.RelationForm(*args, **kwargs)[source]

Bases: GenericModelForm

This form overrides generic form for relation editing. Relations have generic relations to subj and obj, but we hide those ForeignKey form fields and instead show autocomplete choices fields. In addition, one can pass a hx_post_route argument to the form to make the form set the hx-post attribute to the given value. We also pass a reverse boolean, wich gets passed on to the htmx POST endpoint using url parameters (the endpoint can then select the success_url based on the reverse state).

Initialize the form and add the subj and obj fields using the generic apis_entities autocomplete with the correct parameters.

class Meta[source]

Bases: object

fields = '__all__'
widgets = {'obj_content_type': <django.forms.widgets.HiddenInput object>, 'obj_object_id': <django.forms.widgets.HiddenInput object>, 'subj_content_type': <django.forms.widgets.HiddenInput object>, 'subj_object_id': <django.forms.widgets.HiddenInput object>}
base_fields = {}
clean() dict[source]

We check if there are subj or obj fields in the form data and if so, we use the data to create objects for the real fields of the Relation

declared_fields = {}
property media

Return all media required to render the widgets on this form.

property relation_name: str

A helper method to access the correct name of the relation

apis_core.relations.models module

class apis_core.relations.models.Relation(id, subj_content_type, subj_object_id, obj_content_type, obj_object_id)[source]

Bases: Model, GenericModel

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

iscousinof

Accessor to the related object on the reverse side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

ispartof

Accessor to the related object on the reverse side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

issiblingof

Accessor to the related object on the reverse side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

livesin

Accessor to the related object on the reverse side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

classmethod name() str[source]
obj

Provide a generic many-to-one relation through the content_type and object_id fields.

This class also doubles as an accessor to the related object (similar to ForwardManyToOneDescriptor) by adding itself as a model attribute.

obj_content_type

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

obj_content_type_id
classmethod obj_list() list[Model][source]
obj_object_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

property obj_to_subj_text: str
objects = <model_utils.managers.InheritanceManager object>
classmethod reverse_name() str[source]
save(*args, **kwargs)[source]

Save the current instance. Override this in a subclass if you want to control the saving process.

The ‘force_insert’ and ‘force_update’ parameters can be used to insist that the “save” must be an SQL insert or update (or equivalent for non-SQL backends), respectively. Normally, they should not be set.

subj

Provide a generic many-to-one relation through the content_type and object_id fields.

This class also doubles as an accessor to the related object (similar to ForwardManyToOneDescriptor) by adding itself as a model attribute.

subj_content_type

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

subj_content_type_id
classmethod subj_list() list[Model][source]
subj_object_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

property subj_to_obj_text: str
class apis_core.relations.models.RelationModelBase(name, bases, attrs)[source]

Bases: ModelBase

apis_core.relations.models.get_by_natural_key(natural_key: str)[source]

apis_core.relations.querysets module

apis_core.relations.querysets.RelationListViewQueryset(queryset)[source]
apis_core.relations.querysets.RelationViewSetQueryset(queryset)[source]

apis_core.relations.serializers module

class apis_core.relations.serializers.RelationSerializer(*args, **kwargs)[source]

Bases: SimpleObjectSerializer

When a field is instantiated, we store the arguments that were used, so that we can present a helpful representation of the object.

class Meta[source]

Bases: object

fields = ['url', 'label', 'content_type_key', 'content_type_name', 'subj', 'obj']
get_obj(obj)[source]
get_subj(obj)[source]

apis_core.relations.signals module

apis_core.relations.signals.copy_relations(sender, instance, duplicate, **kwargs)[source]
apis_core.relations.signals.merge_relations(sender, instance, entities, **kwargs)[source]

apis_core.relations.tables module

class apis_core.relations.tables.RelationColumn(*args, **kwargs)[source]

Bases: CustomTemplateColumn

template_name = 'columns/relation.html'
verbose_name = ''
class apis_core.relations.tables.RelationsListTable(data=None, order_by=None, orderable=None, empty_text=None, exclude=None, attrs=None, row_attrs=None, pinned_row_attrs=None, sequence=None, prefix=None, order_by_field=None, page_field=None, per_page_field=None, template_name=None, default=None, request=None, show_header=None, show_footer=True, extra_columns=None)[source]

Bases: GenericTable

class Meta[source]

Bases: object

attrs = {'class': 'table-sm'}
exclude = ('desc',)
sequence = ('...', 'view', 'edit', 'delete')
base_columns = {'delete': <apis_core.generic.tables.DeleteColumn object>, 'edit': <apis_core.generic.tables.EditColumn object>, 'relation': <apis_core.relations.tables.RelationColumn object>, 'view': <apis_core.generic.tables.ViewColumn object>}

apis_core.relations.urls module

apis_core.relations.utils module

apis_core.relations.utils.get_all_relation_subj_and_obj() list[ContentType][source]

Return the model classes of any model that is in some way connected to a relation - either as obj or as subj

Returns: list[ContentType]: A list of unique ContentTypes for related models.

apis_core.relations.utils.is_relation(ct: ContentType) bool[source]
apis_core.relations.utils.relation_content_types(subj_model=None, obj_model=None, any_model=None, combination=(None, None)) set[ContentType][source]
apis_core.relations.utils.relation_match_target(relation, target: ContentType) bool[source]

test if a relation points to a target this function should not be cached, because the forward attribute is an annotation that does not seem to be part of the relation, so if cached, method could be called with another forward value and return the wrong result

apis_core.relations.views module

class apis_core.relations.views.CreateRelation(**kwargs)[source]

Bases: Create

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get_form_kwargs(*args, **kwargs) dict[source]

Return the keyword arguments for instantiating the form.

class apis_core.relations.views.CreateRelationForm(**kwargs)[source]

Bases: CreateRelation

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get(*args, **kwargs)[source]

Handle GET requests: instantiate a blank version of the form.

get_form_kwargs(*args, **kwargs) dict[source]

Return the keyword arguments for instantiating the form.

get_success_url() str[source]

Return the URL to redirect to after processing a valid form.

setup(*args, **kwargs) None[source]

Initialize attributes shared by all view methods.

template_name = 'relations/create_relation_form.html'
class apis_core.relations.views.ListRelations(**kwargs)[source]

Bases: TemplateView

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

get(*args, **kwargs)[source]
get_context_data(*args, **kwargs) dict[source]
template_name = 'relations/list_relations.html'