#25139: ModelFormSet: allow swapping unique values
-----------------------------+--------------------
Reporter: jdufresne | Owner: nobody
Type: New feature | Status: new
Component: Forms | Version: master
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------
As a user, I would expect to be able to swap ''unique'' values in an HTML
form backed by a ModelFormSet. Turns out, this is not the case. The user
must do a two step process of first setting the values to temporary value,
then swapping the values. I have created a test case in the Django project
that demonstrates my expectation in tests/model_formsets/tests.py:
{{{
def test_swap_unique_values(self):
p0 = Product.objects.create(slug='car-red')
p1 = Product.objects.create(slug='car-blue')
FormSet = modelformset_factory(Product, fields="__all__")
data = {
'form-TOTAL_FORMS': '2',
'form-INITIAL_FORMS': '2',
# Swap slug values.
'form-0-id': p0.pk,
'form-0-slug': 'car-blue',
'form-1-id': p1.pk,
'form-1-slug': 'car-red',
}
formset = FormSet(data)
self.assertTrue(formset.is_valid())
formset.save()
p0 = Product.objects.get(pk=p0.pk)
self.assertEquals(p0.slug, 'car-blue')
p1 = Product.objects.get(pk=p1.pk)
self.assertEquals(p1.slug, 'car-red')
}}}
However, the form fails to validate on the is_valid() line with the
message "Product with this Slug already exists.".
When thinking about the details, I understand why this happens. But I
don't think it should error in this way. Swapping values is a convenience
that a program can handle without the intervention of a human.
Knowing that in the end all values will be unique, I think the Django form
engine should go ahead with the steps necessary to get there. I think it
is reasonable for a user to expect that they could swap unique values
through an HTML form in this way.
As a point of reference, the following test passes. It demonstrates a user
using temporary values.
{{{
def test_swap_unique_values_two_step(self):
p0 = Product.objects.create(slug='car-red')
p1 = Product.objects.create(slug='car-blue')
FormSet = modelformset_factory(Product, fields="__all__")
data = {
'form-TOTAL_FORMS': '2',
'form-INITIAL_FORMS': '2',
'form-0-id': p0.pk,
'form-0-slug': 'temp0',
'form-1-id': p1.pk,
'form-1-slug': 'temp1',
}
formset = FormSet(data)
self.assertTrue(formset.is_valid())
formset.save()
data = {
'form-TOTAL_FORMS': '2',
'form-INITIAL_FORMS': '2',
# Swap slug values.
'form-0-id': p0.pk,
'form-0-slug': 'car-blue',
'form-1-id': p1.pk,
'form-1-slug': 'car-red',
}
formset = FormSet(data)
self.assertTrue(formset.is_valid())
formset.save()
p0 = Product.objects.get(pk=p0.pk)
self.assertEquals(p0.slug, 'car-blue')
p1 = Product.objects.get(pk=p1.pk)
self.assertEquals(p1.slug, 'car-red')
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/25139>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/052.88bce714b3bc49c5cdd2d12506428980%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.