Source code for django_sorcery.formsets.inline
"""InlineFormSet for sqlalchemy."""
from ..db import meta
from ..forms import ModelForm
from .base import BaseModelFormSet, modelformset_factory
[docs]class BaseInlineFormSet(BaseModelFormSet):
"""A formset for child objects related to a parent."""
def __init__(self, data=None, files=None, instance=None, save_as_new=False, prefix=None, queryset=None, **kwargs):
self.instance = self.fk.parent_model() if instance is None else instance
self.save_as_new = save_as_new
if queryset is None:
queryset = getattr(self.instance, self.fk.name, [])
super().__init__(data, files, prefix=prefix, queryset=queryset, **kwargs)
[docs] def save(self, flush=False, **kwargs):
instances = super().save(flush=flush)
setattr(self.instance, self.fk.name, instances)
return instances
def _get_relation_info(relation):
info = meta.model_info(relation.parent)
rel = info.relationships[relation.key]
if rel.uselist:
return rel
raise ValueError(f"Relationship '{relation}' is not one to many or many to many.")
def _get_foreign_key(relation, parent_model, model, fk_name=None):
info = meta.model_info(parent_model)
if fk_name is None:
relations = [
relation for relation in info.relationships.values() if relation.related_model == model and relation.uselist
]
if len(relations) == 1:
return relations[0]
raise ValueError(f"Couldn't find a relation from '{parent_model.__name__}' to '{model.__name__}'.")
[docs]def inlineformset_factory(
parent_model=None,
model=None,
relation=None,
form=ModelForm,
formset=BaseInlineFormSet,
fk_name=None,
fields=None,
exclude=None,
extra=3,
can_order=False,
can_delete=True,
max_num=None,
formfield_callback=None,
widgets=None,
validate_max=False,
localized_fields=None,
labels=None,
help_texts=None,
error_messages=None,
min_num=None,
validate_min=False,
field_classes=None,
session=None,
):
"""Return an ``InlineFormSet`` for the given kwargs.
``fk_name`` must be provided if ``model`` has more than one
``ForeignKey`` to ``parent_model``.
"""
if relation is not None:
fk = _get_relation_info(relation)
parent_model = fk.parent_model
model = fk.related_model
else:
fk = _get_foreign_key(relation, parent_model, model, fk_name=fk_name)
kwargs = {
"form": form,
"formfield_callback": formfield_callback,
"formset": formset,
"extra": extra,
"can_delete": can_delete,
"can_order": can_order,
"fields": fields,
"exclude": exclude,
"min_num": min_num,
"max_num": max_num,
"widgets": widgets,
"validate_min": validate_min,
"validate_max": validate_max,
"localized_fields": localized_fields,
"labels": labels,
"help_texts": help_texts,
"error_messages": error_messages,
"field_classes": field_classes,
"session": session,
}
FormSet = modelformset_factory(model, **kwargs)
FormSet.fk = fk
return FormSet