model formsets and recently stale data

47 views
Skip to first unread message

Tom

unread,
Jan 25, 2016, 4:07:58 PM1/25/16
to Django developers (Contributions to Django itself)
We saw an unexpected result working with model formsets and recently stale data. 

Consider a simple Book model with soft deletion.

```
class Book(models.Model):
    name = models.CharField(max_length=100)
    deleted = models.BooleanField(default=False)
```

We have one book

```
book = Book.objects.create(name="Grapes of Wrath")
```

and a model formset to edit Books.

```
BookFormSet = modelformset_factory(Book, fields=('name',), max_num=None, extra=0)
```

A user initializes a formset to edit all non-deleted books. While that user is filling out the edit form, another user deletes the book.

```
# The user calls a view that initializes the formset. 
formset = BookFormSet(queryset=Book.objects.filter(deleted=False))
data = {
            'form-TOTAL_FORMS': '1',
            'form-INITIAL_FORMS': '1',
            'form-MAX_NUM_FORMS': '',
            'form-0-id': book.pk,
            'form-0-name': "New Title"
    }

# Before submission, another user deletes the book. 
book.deleted = True
book.save()

# Now the original user submits the form
formset = BookFormSet(data=data, queryset=Book.objects.filter(deleted=False))
formset.is_valid()  # True
formset.save()
```

Two Books now exist. Despite having `data['form-0-id'] = book.pk` and extra=0, django uses a ModelForm with instance=None, which ends up creating a new row. This is because BaseModelFormSet's _existing_object returns None if the submitted id is not in the queryset's set of ids. https://github.com/django/django/blob/master/django/forms/models.py#L573

Is this expected? If an id is submitted with a form, and that id isn't expected, could it make sense for formset validation to fail instead? 







Reply all
Reply to author
Forward
0 new messages