OneToOneField not updating relationship with reverse relation after refresh_from_db()

512 views
Skip to first unread message

Shivam Jindal

unread,
Sep 2, 2018, 1:00:42 PM9/2/18
to django-d...@googlegroups.com
I have the following model

class Member(models.Model):
    user = models.OneToOneField(User, null=True, blank=True)

Operation sequence

m = Member.objects.get(id=4) # This objects has attached user
m.user # Print user objects successfully
m1 = Member.objects.get(id=4) # Fetch same object from db 
m1.user = None
m1.save() # Remove user object from above member

m.user.refresh_from_db()
m.user.member # It is printing the member object which was linked previously, but the user object should not have attached member object because the relationship should had been updated by calling refresh_from_db()  

--
Shivam Jindal
Software Developer | Josh Technology Group

CONFIDENTIALITY NOTICE: The information contained in this e-mail is for the intended recipient(s) alone. It may contain privileged and confidential information that is exempt from disclosure under applicable law. If you have received this email in error, please notify the sender of the error and delete this message immediately.

Ian Foote

unread,
Sep 2, 2018, 2:54:18 PM9/2/18
to django-d...@googlegroups.com
On 02/09/18 17:58, Shivam Jindal wrote:
> I have the following model
>
> class Member(models.Model):
>     user = models.OneToOneField(User, null=True, blank=True)
>
> *Operation sequence*
>
> m = Member.objects.get(id=4) # This objects has attached user
> m.user # Print user objects successfully
> m1 = Member.objects.get(id=4) # Fetch same object from db 
> m1.user = None
> m1.save() # Remove user object from above member
>
> *m.user.refresh_from_db()*
> *m.user.member* # It is printing the member object which was linked
> previously, but the user object should not have attached member object
> because the relationship should had been updated by calling
> *refresh_from_db()*  
>

Hi Shivam,

I don't believe this is actually a bug. You're refreshing m.user, not m
itself, so as far as m is concerned m.user hasn't changed. If you use
m.refresh_from_db() instead you should see m.user updated to None.

Hope this helps,
Ian

Shivam Jindal

unread,
Sep 2, 2018, 3:03:41 PM9/2/18
to django-d...@googlegroups.com
Hi Lan,

m.user.refresh_from_db() is sam as 

u = m.user
u.refresh_from_db()

So If I am refreshing u, it should update all relationship and property of u(including reverse relation). Should It not?


--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscribe@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/8df15e03-4d44-225d-7116-6954d0821362%40feete.org.
For more options, visit https://groups.google.com/d/optout.



--
Shivam Jindal
Software Developer | Josh Technology Group

Ian Foote

unread,
Sep 2, 2018, 3:40:33 PM9/2/18
to django-d...@googlegroups.com
On 02/09/18 19:59, Shivam Jindal wrote:
> Hi Lan,
>
> *m.user.refresh_from_db()* is sam as 
>
> *u = m.user*
> *u.refresh_from_db()*
>
> So If I am refreshing u, it should update all relationship and property
> of *u*(including reverse relation). Should It not?
>

Hi Shivam,

As far as I can tell, u.refresh_from_db() only cares about making sure
u's state is in sync with the database. It doesn't care about the state
of any related objects, like m.

I suspect that cascading the sync to related objects would be difficult
to get right and might be unexpected behaviour to other users. I'm still
not convinced this is a bug and even if it is, I think it would require
a deprecation cycle to change, so I don't think it would be worth it.
Just calling m.refresh_from_db() instead seems sufficient to me.

Ian

Adam Johnson

unread,
Sep 4, 2018, 2:18:14 PM9/4/18
to django-d...@googlegroups.com
Correct, refresh_from_db() is expected to only update the current model, not traverse to others linking it (which could be *many*). You'd want m.refresh_from_db() to refresh the fact that the user field on m has changed.

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.


--
Adam

Shivam Jindal

unread,
Sep 4, 2018, 2:34:41 PM9/4/18
to django-d...@googlegroups.com
Actually, I was calling listener for user object So I needed the update user object. Currently, I have fetched the user object again( after saving member object) by calling User.objects.get(id=m.user_id) 

On Tue, Sep 4, 2018 at 11:47 PM, Adam Johnson <m...@adamj.eu> wrote:
Correct, refresh_from_db() is expected to only update the current model, not traverse to others linking it (which could be *many*). You'd want m.refresh_from_db() to refresh the fact that the user field on m has changed.
On Sun, 2 Sep 2018 at 20:40, Ian Foote <i...@feete.org> wrote:
On 02/09/18 19:59, Shivam Jindal wrote:
> Hi Lan,
>
> *m.user.refresh_from_db()* is sam as 
>
> *u = m.user*
> *u.refresh_from_db()*
>
> So If I am refreshing u, it should update all relationship and property
> of *u*(including reverse relation). Should It not?
>

Hi Shivam,

As far as I can tell, u.refresh_from_db() only cares about making sure
u's state is in sync with the database. It doesn't care about the state
of any related objects, like m.

I suspect that cascading the sync to related objects would be difficult
to get right and might be unexpected behaviour to other users. I'm still
not convinced this is a bug and even if it is, I think it would require
a deprecation cycle to change, so I don't think it would be worth it.
Just calling m.refresh_from_db() instead seems sufficient to me.

Ian

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscribe@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.


--
Adam

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscribe@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Shivam Jindal
Software Developer | Josh Technology Group
Reply all
Reply to author
Forward
0 new messages