Django

Code

Ticket #9493 (closed: fixed)

Opened 1 year ago

Last modified 9 months ago

Formsets with data that violates unique constraints across forms are not marked invalid

Reported by: Alex Assigned to: Alex
Milestone: 1.1 Component: Forms
Version: 1.0 Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: 1 Needs documentation: 0
Needs tests: 0 Patch needs improvement: 1

Description

If I have a form with a unique name field, and I submit data that is a dupe of something in the db, it fails validation, however if I have a formset and I submit the same data 2x in the same formset, it passes validation and fails at the save level.

Attachments

formset-unique.diff (2.9 kB) - added by Alex on 11/01/08 14:23:34.
needs test for unique_together and docs
formset-unique.2.diff (3.6 kB) - added by Alex on 11/01/08 14:34:46.
added tests for unique_together
formset-unique.3.diff (4.6 kB) - added by Alex on 11/01/08 14:46:46.
made it a little more effiecient and add docs
formset_unique.4.diff (4.3 kB) - added by mrts on 11/02/08 06:27:33.
Minor nitpicking
formset-unique.4.diff (4.5 kB) - added by Alex on 11/03/08 10:34:13.
formset-unique.5.diff (4.5 kB) - added by Alex on 01/20/09 15:19:14.
formset-unique.6.diff (5.1 kB) - added by Alex on 01/20/09 15:36:23.
formset-unique.7.diff (8.3 kB) - added by Alex on 03/30/09 15:39:39.
formset-unique.8.diff (7.8 kB) - added by Alex on 03/30/09 17:33:31.
formset-unique.9.diff (7.8 kB) - added by Alex on 04/18/09 11:08:54.
formset-unique.10.diff (11.3 kB) - added by Alex on 05/05/09 15:28:23.
added the date stuff and removed code duplication. Not sure what to do to make the formset errors more user friendly. Also needs tests in the worst way (I'll do this during the EDC sprint in all likelyhood)
formset-unique.11.diff (13.4 kB) - added by Alex on 05/07/09 05:48:49.
formset-unique.12.diff (14.6 kB) - added by Alex on 05/07/09 05:59:32.
formset-unique.13.diff (16.0 kB) - added by Alex on 05/07/09 06:18:19.

Change History

11/01/08 14:18:04 changed by brosner

  • status changed from new to assigned.
  • needs_better_patch changed.
  • needs_tests changed.
  • summary changed from Formsets with data that violates unique constraints across forms are not mared invalid to Formsets with data that violates unique constraints across forms are not marked invalid.
  • owner changed from Alex to brosner.
  • needs_docs changed.
  • stage changed from Unreviewed to Accepted.

11/01/08 14:18:53 changed by brosner

#8882 was really the original problem, but since that ticket grew a bit too big, lets use this ticket to track this individual problem.

11/01/08 14:23:34 changed by Alex

  • attachment formset-unique.diff added.

needs test for unique_together and docs

11/01/08 14:34:46 changed by Alex

  • attachment formset-unique.2.diff added.

added tests for unique_together

11/01/08 14:46:46 changed by Alex

  • attachment formset-unique.3.diff added.

made it a little more effiecient and add docs

11/02/08 06:24:38 changed by mrts

Thanks to you both for working on this!

I've attached an updated patch with the following minor changes -- sorry for the nitpicking, the patch looks generally good and works well. Also, note that the updated patch has been tested (both by running the testcase and in admin).

1

Why do we need to copy the list on line 943 of the patch

unique_together = self.forms[0].instance._meta.unique_together[:]

and discard it right afterwards (by reusing the unique_together variable name on next line)? Wouldn't

unique_together = [check for check in self.forms[0].instance._meta.unique_together if [True for field in check if field in self.forms[0].fields]]

be more appropriate?

2

Similarly, wouldn't it make sense to avoid using the bad_fields intermediary and use errors directly instead?

3

If there is only one field (i.e. it is a unique, not unique together test), it probably makes sense to call force_unicode (or indeed, just unicode) directly instead of get_text_list:

if len(unique_check) == 1:
    errors.append(_(u"You have entered duplicate data for %(field)s, all %(field)ss should be unique." % { 'field': force_unicode(field), }))

4

I'd say creating tuple([form.cleaned_data[field] for field in unique_check]) twice in if tuple([form.cleaned_data[field] for field in unique_check]) in data: ... else: data.add(tuple([form.cleaned_data[field] for field in unique_check])) should be avoided.

11/02/08 06:27:33 changed by mrts

  • attachment formset_unique.4.diff added.

Minor nitpicking

11/02/08 13:14:15 changed by Alex

1) The reason for this is it leads to long and unruly lines, I think this makes it a tad easier to follow.

2) Yes, this can be done, I don't think there is much of a speed difference, and I do think it's easier to read the other way. But however(FWIW this is how it's done for ModelForms? as well).

3) Yeah, that should be changed, you need to do field[0] though, as field itself is a tuple.

4) Yes.

11/02/08 14:37:05 changed by mrts

Alex, if you have time please take a look at the attached patch and improve it further if you see something worth amending (it looks final-ish to me).

(As for The reason for this is it leads to long and unruly lines, I think this makes it a tad easier to follow, I mainly had in main avoiding copying (i.e. foo = a_list instead of foo = a_list[:]. Copying is usually required if the local copy is modified -- but not in this case.)

11/02/08 14:48:18 changed by mrts

3) Yeah, that should be changed, you need to do field[0] though, as field itself is a tuple. -- field is a field from unique_check (a tuple), not unique_checks (a list of tuples), thus not a . The patch has a bit different structure, although your idea remains exactly the same.

11/02/08 14:50:54 changed by mrts

... "thus not a tuple" :)

11/03/08 10:34:13 changed by Alex

  • attachment formset-unique.4.diff added.

01/02/09 16:41:51 changed by Alex

  • owner changed from brosner to Alex.
  • status changed from assigned to new.

01/20/09 15:19:14 changed by Alex

  • attachment formset-unique.5.diff added.

01/20/09 15:36:23 changed by Alex

  • attachment formset-unique.6.diff added.

03/20/09 06:03:15 changed by mrts

  • has_patch set to 1.
  • milestone set to 1.1.

It's a bug in both 1.0 and 1.1, marking as such.

03/30/09 15:39:39 changed by Alex

  • attachment formset-unique.7.diff added.

03/30/09 17:33:31 changed by Alex

  • attachment formset-unique.8.diff added.

03/31/09 22:15:36 changed by Alex

  • stage changed from Accepted to Ready for checkin.

04/10/09 05:08:48 changed by mrts

#10769, #10770 were duplicates.

04/18/09 11:08:54 changed by Alex

  • attachment formset-unique.9.diff added.

05/01/09 06:57:04 changed by russellm

  • needs_better_patch set to 1.
  • stage changed from Ready for checkin to Accepted.

On the whole, this patch looks good. However, I have two comments:

  1. The patch needs to be updated to include the formset analog of #10134/[10646] (avoiding duplication of logic, if possible).
  2. While this patch correctly catches the error condition, I'm not satisfied with the way the error is reported. Consider the use case where you have 100 inline forms - a top level "There's a duplicate" error doesn't really help identify the pair of forms that is actually causing the problem. In addition to the formset level error, the individual forms should be marked as being in error.

05/05/09 15:28:23 changed by Alex

  • attachment formset-unique.10.diff added.

added the date stuff and removed code duplication. Not sure what to do to make the formset errors more user friendly. Also needs tests in the worst way (I'll do this during the EDC sprint in all likelyhood)

05/07/09 05:48:49 changed by Alex

  • attachment formset-unique.11.diff added.

05/07/09 05:59:32 changed by Alex

  • attachment formset-unique.12.diff added.

05/07/09 06:18:19 changed by Alex

  • attachment formset-unique.13.diff added.

05/07/09 06:25:00 changed by jacob

  • stage changed from Accepted to Ready for checkin.

05/07/09 07:17:52 changed by russellm

  • status changed from new to closed.
  • resolution set to fixed.

(In [10682]) Fixed #9493 -- Corrected error handling of formsets that violate unique constraints across the component forms. Thanks to Alex Gaynor for the patch.

05/08/09 11:04:59 changed by russellm

(In [10718]) [1.0.X] Fixed #9493 -- Corrected error handling of formsets that violate unique constraints across the component forms. Thanks to Alex Gaynor for the patch.

Merge of r10682 from trunk.


Add/Change #9493 (Formsets with data that violates unique constraints across forms are not marked invalid)




Change Properties
Action