Skip to main content

JavaScript-enhanced dynamic formsets using Bootstrap

Project description


  • django-bootstrap3
  • jQuery
  • jQuery UI


  • pip install django-bootstrap-dynamic-formsets


  • Add django_bootstrap_dynamic_formsets to Applications in your If you haven’t done so already, add django-bootstrap3 as well.
  • Create a regular model, form and formset. If you need dynamic order functionality, in the fields parameter of the formset factory, do not include a custom order field. Instead, set can_order to True. Set can_delete to True as well, if you wish to be able to delete forms.
  • Write your view as you would for a regular formset, with one exception:
    • If can_order is True,you need to specifically save the order, Django will not do this for you! Check out the example below.
  • In your template, load the custom template tag library.
    • {% load bootstrap_dynamic_formsets %}
  • Use the provided custom tag where you’d like to place the formset.
    • {% bootstrap_dynamic_formset formset can_order=True can_delete=True layout="horizontal" %}
    • where formset is your formset and
    • can_order and can_delete are set accordingly to how you set them in your formset. Their default value if you don’t specify anything is False
    • Optionally, you can add the form_wrapper parameter. This is the class that surrounds every form instance. Default: form_wrapper="well"
    • Also optionally, you can choose which Bootstrap form layout to use. Options are "", "inline" or "horizontal"
  • Make sure you don’t forget to include jQuery and jQuery UI in your template.
  • The form submit button has to have the id form-submit
  • In your browser
    • Order forms by dragging and dropping them. You can grab them on the move icon.
    • Alternatively, you can use the up/down buttons.
    • Delete a form by clicking on the trash icon. It will disappear. You cannot undo this. However, the database will only be changed if you click submit.
    • Add a new form below the current one by clicking the plus icon.
    • Submit the changed data by hitting submit.


For this example, we are going to use a simple model called Album:

class Album(models.Model):
    artist = models.CharField(max_length=75)
    name = models.CharField(max_length=100)
    release = models.DateField()
    order = models.IntegerField(blank=True, null=True)

To make this simple, let’s use a model formset instead of creating a custom form and formset. Also, add everything else that is needed for your view.

def manage_albums(request):
    AlbumFormSet = modelformset_factory(Album, can_order=True, can_delete= True,
    if request.method == 'POST':
        formset = AlbumFormSet(request.POST, request.FILES)
        if formset.is_valid():
            for form in formset.ordered_forms:
                form.instance.order = form.cleaned_data['ORDER']
            messages.success(request, u"Formset edited successfully.")
            return HttpResponseRedirect(reverse('formsets'))
            messages.error(request, u"Please correct the errors below.")

        formset = AlbumFormSet(queryset=Album.objects.order_by('order'))
    return render(request, 'manage_albums.html', {'formset': formset})

Notice a few things:

  • order is not included in fields
  • The for-loop is necessary to save the order. Just calling will not save it.

Finally, let’s write the template. This is actually very easy:


{% load bootstrap_dynamic_formsets %}
{% bootstrap_dynamic_formset formset %}

That’s it!

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for django-bootstrap-dynamic-formsets, version 0.4.3
Filename, size File type Python version Upload date Hashes
Filename, size (10.6 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page