Hi all,

continuing my previous post, I've implemented most of the ideas mentioned in this thread now, and would like, for completeness and future reference, add some related findings and thoughts:

As mentioned in my previous post, reconstructing the formset's initial data (the queryset) in the POST request by the same parameters that were used to construct the queryset for the initial formset data in the GET request, in *addition* to the primary keys received in the POST request, turned out to work very well. That is, the code is roughly like this:

    # Inits is made from the view's appropriate queryset.
    Inits = ...

    # In the case of the GET request:
    formset = TestFormSet(initial=Inits)

    # In the case of the POST request:
    formset = TestFormSet(request.POST, initial=Inits)


This is how the initial data is useful in the POST request:

- It is required for validation in order to be able to detect "high-level" kinds of concurrency related mismatches (number of instances changed, deleted instances, unexpected new or replaced instances).

- We also need the same data for "low-level" concurrency control, e.g. checking a `VERSION` number as e.g. in [1] and [2].

- As a side effect of the same validation steps, tampering with the POST data is detected as well.

- The initial data (`Inits` above) is also a convenient place for storing arbitrary extra data, e.g. the actual model instances, that can be used for rendering additional information in the template.

- In the case of successful formset validation, the readily available queryset instances can be used for storing and saving the submitted data.


I still use custom Forms for all this, not ModelForms, because:

- As we need the model instances anyway and already got them via the queryset as described above, using a ModelForm(-set) that implicitly instantiates them all again would not be efficient.

- I have a lot of cases where I have a field flagged as "required" in the model, but "not required" in the form. This helps with making entire forms optional in the formset (won't get saved if not filled out), but makes clear what is required when a model is eventually saved. This is especially helpful when forms are rendered for which not necessarily a model instance exists and is not necessarily created, as e.g. in my CalenderEntry example described in another post of this thread ([3]).

- Foreign keys are problematic. Although a ModelForm covers a FK just as it covers the model's PK, if we wish to extend the concept of validating `VERSION` numbers (as above) also to the related models, the form must be augmented with an appropriate version number field for each FK. (I have not checked, but adding such extra fields is probably possible with ModelForms as well.)


Well, so far my findings. Although this seems to work well, I'd very much appreciate any further comments and thoughts.

Best regards,
Carsten


[1] https://github.com/saxix/django-concurrency
[2] https://github.com/gavinwahl/django-optimistic-lock
[3] https://groups.google.com/d/msg/django-users/R7wJBTlC8ZM/N3dNlMrGCwAJ


--
You received this message because you are subscribed to the Google Groups "Django 
users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/5632477F.4050107%40cafu.de.
For more options, visit https://groups.google.com/d/optout.

Reply via email to