mirror of
https://github.com/django/django.git
synced 2025-10-24 14:16:09 +00:00
Fixed #18906 -- Ignored to-be-deleted forms in formset validate_unique
Thanks c.pollock at bangor.ac.uk for the report.
This commit is contained in:
@@ -179,11 +179,10 @@ class BaseFormSet(object):
|
||||
@property
|
||||
def deleted_forms(self):
|
||||
"""
|
||||
Returns a list of forms that have been marked for deletion. Raises an
|
||||
AttributeError if deletion is not allowed.
|
||||
Returns a list of forms that have been marked for deletion.
|
||||
"""
|
||||
if not self.is_valid() or not self.can_delete:
|
||||
raise AttributeError("'%s' object has no attribute 'deleted_forms'" % self.__class__.__name__)
|
||||
return []
|
||||
# construct _deleted_form_indexes which is just a list of form indexes
|
||||
# that have had their deletion widget set to True
|
||||
if not hasattr(self, '_deleted_form_indexes'):
|
||||
|
||||
@@ -520,9 +520,9 @@ class BaseModelFormSet(BaseFormSet):
|
||||
# Collect unique_checks and date_checks to run from all the forms.
|
||||
all_unique_checks = set()
|
||||
all_date_checks = set()
|
||||
for form in self.forms:
|
||||
if not form.is_valid():
|
||||
continue
|
||||
forms_to_delete = self.deleted_forms
|
||||
valid_forms = [form for form in self.forms if form.is_valid() and form not in forms_to_delete]
|
||||
for form in valid_forms:
|
||||
exclude = form._get_validation_exclusions()
|
||||
unique_checks, date_checks = form.instance._get_unique_checks(exclude=exclude)
|
||||
all_unique_checks = all_unique_checks.union(set(unique_checks))
|
||||
@@ -532,9 +532,7 @@ class BaseModelFormSet(BaseFormSet):
|
||||
# Do each of the unique checks (unique and unique_together)
|
||||
for uclass, unique_check in all_unique_checks:
|
||||
seen_data = set()
|
||||
for form in self.forms:
|
||||
if not form.is_valid():
|
||||
continue
|
||||
for form in valid_forms:
|
||||
# get data for each field of each of unique_check
|
||||
row_data = tuple([form.cleaned_data[field] for field in unique_check if field in form.cleaned_data])
|
||||
if row_data and not None in row_data:
|
||||
@@ -554,9 +552,7 @@ class BaseModelFormSet(BaseFormSet):
|
||||
for date_check in all_date_checks:
|
||||
seen_data = set()
|
||||
uclass, lookup, field, unique_for = date_check
|
||||
for form in self.forms:
|
||||
if not form.is_valid():
|
||||
continue
|
||||
for form in valid_forms:
|
||||
# see if we have data for both fields
|
||||
if (form.cleaned_data and form.cleaned_data[field] is not None
|
||||
and form.cleaned_data[unique_for] is not None):
|
||||
@@ -611,10 +607,7 @@ class BaseModelFormSet(BaseFormSet):
|
||||
return []
|
||||
|
||||
saved_instances = []
|
||||
try:
|
||||
forms_to_delete = self.deleted_forms
|
||||
except AttributeError:
|
||||
forms_to_delete = []
|
||||
forms_to_delete = self.deleted_forms
|
||||
for form in self.initial_forms:
|
||||
pk_name = self._pk_field.name
|
||||
raw_pk_value = form._raw_value(pk_name)
|
||||
|
||||
Reference in New Issue
Block a user