This is probably not a bug and just a consequence of what I'm trying
to do (and probably not doing it in a very good way), so this is not
me saying "something needs to be fixed or changed", just observing.

I have a model class of "Document" which has a file field on it and is
set up to have a GenericForeignKey field which can be blank. I have a
variety of other classes which have GenericRelation fields to point
back to it. What I want to do is treat them a bit like a ManyToMany
field on a form.

The UI for the GenericRelation fields that point to documents consists
of listing any existing documents set in the field, allowing documents
to be removed from the field and also providing a popup dialogue which
allows new documents to be created (they get saved through the popup
dialogue but with the GenericForeignKey field set to blank).

The first thing I hit was that "GenericRelation" fields are forced to
to have "editable" set to False, so the model form creation skips 'em.
So I declared them on the form as ModelMultipleChoiceField (for the
purposes of having something vaguely sensible there) but using my own
custom code to render the widget. When the form is submitted the value
for the widget consists of id values for the Document objects selected
and ModelMultipleChoiceField's clean method turns it into a list of
Document objects. So far so good.

save_m2m fires and so __set__ gets called for the GenericRelation
field and that's where I hit a problem because __set__ assumes that
the value being assigned to it contains none of the prior values so
calls .clear() before then doing .add() for each item.

So if you had a field called "somegenericrelation" on an instance
which had some values (i.e. objects related via the relation) then
doing "instance.somegenericrelation=instance.somegenericrelation" will
delete all the items and then add them ... Now as ..save() on a model
instance will do an "INSERT" if the record doesn't exist when what
would happen usually is that the table entries (in my case for
Document) would be deleted and reinserted. As "Document" has a file
field what happens is the file gets deleted on disk by the file
manager during the deletion and then of course although the record for
the Document gets recreated the file is now gone.

So from this I suspect having a GenericRelation field appear on a form
is bad and I'm probably doing something I shouldn't - alternatively
maybe it's an area/use of contenttypes that's been overlooked?

I also suspect that assigning to a GenericRelation field a list of
values that includes items already assigned to it is bad and shouldn't
be done (and because I'm doing a bad thing in using it on a form I'm
making the django form stuff do this bad thing itself) - alternatively
maybe __set__ on ReverseGenericRelatedObjectsDescriptor could be a bit
more clever and not delete any objects its going to add back again
with .add.

Matt



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to