I thought I'd share what I found and where I got stuck in case someone
wants to shed some light on the matter. I realize that my knowledge of
Django's inner structure is nowhere near sufficient to be able to find
an elegant solution at the first stab. I took this more as a learning
experience for myself, since someone might even be already coding a
solution.
Anyway, I figured that Django should check the uniqueness of
unique_together fields in the same piece of code as it validates
individual fields. It seems that BaseForm.full_clean() is that place.
The hook for validations not specific to a single field calls
BaseForm.clean(), so maybe that's the best place to put
unique_together validation?
Admin creates forms with the form_for_model() method, and as a
consequence they get a _model attribute which points to the class of
the model which the form represents. So unique_together validation
should be done only if the form's self._model is set and
self._model._meta.unique_together is non-empty. Right?
A query should then be made with the unique_together field and their
corresponding values from the form as filter criteria. But in the case
of inline forms, one of the unique_together fields could be the
foreign key to the parent model inside which the inline form is
displayed. For existing inline objects, the form's self.initial dict
contains the id for the parent form's object, but the empty inline
forms for adding new objects don't include that value.
So the first problem is, how to pass the parent form's object id to
the inline forms when the foreign key is part of unique_together.
This is where I got stuck.
I'd appreciate if someone could show me where I took a wrong turn, or,
if I'm on the right track, give some insight as to how to proceed from
here.
I think you're looking at the wrong level, slightly. The unique_together
requirement is a property of the model, not the form. So it should
really be checked as part of model validation.
There's a missing piece at the moment in that model-aware validation
isn't complete. However, Jacob and I sat down at OSCON and worked out
how to fill this in and Jacob started writing some code. So this
shouldn't be miles off into the future. At that point, part of
validating a form that is hooked to a model will be calling
model.validate(). The advantage here is that a model instance already
knows how to access it's own related entries, so you don't have to go
through all the hoops when constructing a query.
Until then, I'm not sure that dropping in a bunch of workarounds to do
what is essentially model validation in the form processing code is
going to be the right approach. Better to fix the main problem correctly
than take two steps back before three steps forward.
I realise that isn't an ideal situation from your point of view, because
it's hard to move forwards without Jacob's code. However, that's really
the smoothest solution as far as fitting in with the overall Big Picture
and having the right components do the right work.
Regards,
Malcolm
--
Tolkien is hobbit-forming.
http://www.pointy-stick.com/blog/
That's basically what I hoped to hear :)
I started looking at model validation in the db model and admin
modules, but following the code led me to newforms, which did left me
wondering if something's still missing.
Thanks for the update, I'll stay alert and jump in to test the new
stuff as soon as it's done.
-Antti