On Tue, May 14, 2013 at 7:38 AM, Shai Berger <s...@platonix.com> wrote:
> On Tuesday 14 May 2013, Alex Ogier wrote: > > > > It's a totally new behavior that has > > plenty of corner cases such as foreign keys, and especially > OneToOneFields. > > > Another one is initializers: get() or any other method of fetching an > object > from the database will call __init__() with the fields as *args; this > allows a > model to manipulate these fields or calculate derived fields or whatever. > refresh() may put such objects in an inconsistent state by default -- to > prevent this, we would need a rule along the lines of "every model that > overrides __init__() also needs to override refresh()". There's also a systemic problem with any field that contains a python reference. What happens when the value mutates in the database? Do you create new instances of the value? What if it *didn't* mutate, how do you know that? Imagine a hypothetical python dict field, that serializes a Python dict to JSON or a string or something and stores it in the database. What happens in the following case? a = A(dict_field={"hello": "world"}) d = a.dict_field a.save() a.refresh() d["hello"] = "planet" # does this mutate a.dict_field? does the answer change if somebody changed the database in between saving and refreshing? In the case of the OneToOneField, we need that the related Python instance not be changed if the value didn't change, or else we will break the one-to-one correspondence of the Python instances (two related one-to-one models point back to our model). There doesn't really seem to be any way to do that generally, so you probably have to create new instances every time even when the value doesn't change except in this special case. Are OneToOneFields special enough to warrant that? What about just your average many-to-one relationship ("b = a.b_set[0]; a.refresh(); assert b not in a.b_set")? Basically, having a .refresh() necessitates having mutation semantics on fields, where previously fields (not including deferred fields) were always immutable. Either you are loading a new instance from the database, or you are mutating a python value and re-serializing it to the database format. You never have to reconcile python mutations with database mutations. Even deferred fields have only one allowed mutation - from uninitialized to initialized. Best, Alex Ogier -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.