Skip to content

Instantly share code, notes, and snippets.

@mgd020
Last active August 11, 2016 01:09
Show Gist options
  • Save mgd020/f1497767b9ed959b1dee90c503363182 to your computer and use it in GitHub Desktop.
Save mgd020/f1497767b9ed959b1dee90c503363182 to your computer and use it in GitHub Desktop.
create formset data with dicts, and modelformset data with models
from django.forms import formsets, model_to_dict
from django.http.request import QueryDict
def formset_data_factory(formset_class, dicts, extra_fields=None):
data = QueryDict(mutable=True)
form = formset_class.form
prefix = (form.prefix or formset_class.get_default_prefix()) + '-'
fields = form.declared_fields.viewkeys() | form.base_fields.viewkeys()
if extra_fields:
fields |= set(extra_fields)
if formset_class.can_delete:
fields.add(formsets.DELETION_FIELD_NAME)
if formset_class.can_order:
fields.add(formsets.ORDERING_FIELD_NAME)
data[prefix + formsets.TOTAL_FORM_COUNT] = len(dicts)
data[prefix + formsets.INITIAL_FORM_COUNT] = 0
for i, d in enumerate(dicts):
i_prefix = prefix + '{}-'.format(i)
d.setdefault(formsets.ORDERING_FIELD_NAME, i)
for field in fields:
data[i_prefix + field] = d.get(field, '')
return data
def modelformset_data_factory(modelformset_class, objects, deleted_objects=None, extra_fields=None):
form_meta = modelformset_class.form._meta
pk_field = form_meta.model._meta.pk.name
fields = (set(form_meta.fields) | {pk_field}) if form_meta.fields else None
exclude = (set(form_meta.exclude) - {pk_field}) if form_meta.exclude else None
dicts = [dict(model_to_dict(obj, fields, exclude), **{formsets.ORDERING_FIELD_NAME: i}) for i, obj in enumerate(objects)]
if deleted_objects:
dicts += [dict(model_to_dict(obj, fields, exclude), **{formsets.DELETION_FIELD_NAME: 'on'}) for obj in deleted_objects]
if extra_fields:
extra_fields = set(extra_fields) + pk_field
else:
extra_fields = (pk_field,)
return formset_data_factory(modelformset_class, dicts, extra_fields)
def inlineformset_data_factory(inlineformset_class, objects, deleted_objects=None, extra_fields=None):
fk_field = inlineformset_class.fk.name
if extra_fields:
extra_fields = set(extra_fields) + fk_field
else:
extra_fields = (fk_field,)
return modelformset_data_factory(inlineformset_class, objects, deleted_objects, extra_fields)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment