Hi all,
tl;dr: saving inherited model overwrites fields in parent models with empty
strings
I have the following models:
class Contact(models.Model):
comment = models.CharField(max_length=255, blank=True)
emails = models.ManyToManyField(
Email,
blank=True,
through='ContactEmail',
through_fields=('contact', 'email'),
)
# couple of more manytomanys, to addresses, phones, etc
class ContactEmail(BaseContactJunctionModel):
email = models.ForeignKey(Email, null=True, on_delete=models.SET_NULL)
contact = models.ForeignKey(Contact, on_delete=models.CASCADE)
event = models.ForeignKey(ContactEvent, on_delete=models.PROTECT)
event_date = models.DateTimeField(default=timezone.now)
# other similar through tables for the rest of the manytomanys and their
target models
class Organisation(Contact):
name = models.CharField(max_length=255, blank=True)
hierarchy = models.ManyToManyField(
'self',
blank=True,
symmetrical=False,
through='OrganisationHierarchy',
through_fields=('sender', 'target'),
)
# again, more manytomanys, not to self though
# not sure this is relevant but as it's to self, then just in case
class OrganisationHierarchy(BaseContactJunctionModel):
# this, instance that specifies relationship
sender = models.ForeignKey(
Organisation,
null=True,
related_name='senders',
on_delete=models.SET_NULL,
)
# instance that 'this' or 'sender' is related to
target = models.ForeignKey(
Organisation,
null=True,
related_name='targets',
on_delete=models.SET_NULL,
)
connection_type = models.ForeignKey(
ConnectionType,
null=True,
on_delete=models.PROTECT,
)
I have a view based on CreateView and a template to capture user
input. The post request coming from browser is a-ok, saving
emails, contact, contactemails and other manytomany targets and
junction tables works without a problem but when getting to
saving Organisation, this happens (pseudocode):
save() is called from django/db/models/base.py
save_base() is called with self=Organisation
save_base calls _save_parents(self=Organisation, cls=Organisation)
save_parents loops through cls._meta.parents and comes across
relation
parent=Contact, field=Organisation.contact_ptr
calls _save_table with self=Organisation and cls=Contact
_save_table finds from cls._meta that it has
local concrete field "comment" and stores it in list
non_pks
it then finds the values for those fields like
this:
f.pre_save(self, false) for f in non_pks
I then see a call to _update in queries.py and Contact instance
is updated with new values.
I don't really understand what's happening here, the code finds
local concrete fields from "cls" which at this point is Contact
and comes up, correctly, with "comment" but then it tries to
query the field value form "self" which at this point is
Organisation object. I'm not sure why Organisation has "comment"
attribute at all, because the way I read the docs it should only
happen when the base model is abstract or when the inherited
model is proxy model, neither of which is the case. Anyway, the
value returned by save_base for the "comment" from "self" is not
the value I inserted into the form field (and what has previously
been saved to Contact object) but is instead an empty string.
The end result is, after Contact object is correctly saved it is,
moments later, overwritten by an empty string. Does anybody have
a clue as to what is happening and most importantly, how can I
avoid it?
Thanks,
--
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-users/4587198f-5f6f-49a7-b54a-1dcfe5a436ab%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.