- django-bootstrap3
- jQuery
- jQuery UI
- pip install django-bootstrap-dynamic-formsets
- Add django_bootstrap_dynamic_formsets to Applications in your settings.py. 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
fieldsparameter of the formset factory, do not include a custom order field. Instead, setcan_orderto True. Setcan_deleteto 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_orderis True,you need to specifically save the order, Django will not do this for you! Check out the example below.
- If
- 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
formsetis your formset and can_orderandcan_deleteare set accordingly to how you set them in your formset. Their default value if you don't specify anything isFalse- Optionally, you can add the
form_wrapperparameter. 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:
models.py
...
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.
views.py
...
def manage_albums(request):
AlbumFormSet = modelformset_factory(Album, can_order=True, can_delete= True,
fields=['artist','name','release',])
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']
formset.save()
messages.success(request, u"Formset edited successfully.")
return HttpResponseRedirect(reverse('formsets'))
else:
messages.error(request, u"Please correct the errors below.")
else:
formset = AlbumFormSet(queryset=Album.objects.order_by('order'))
return render(request, 'manage_albums.html', {'formset': formset})
...
Notice a few things:
orderis not included infields- The for-loop is necessary to save the order. Just calling
formset.save()will not save it.
Finally, let's write the template. This is actually very easy:
manage_albums.html
...
{% load bootstrap_dynamic_formsets %}
...
{% bootstrap_dynamic_formset formset %}
...
That's it!
- mattions
- singalen
- MikeSandford