Opened 4 years ago
Closed 4 years ago
#32524 closed Bug (invalid)
unexpected behavior when using gettattr for related object
Reported by: | elonzh | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.1 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | yes |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Assuming we have a model like that:
class UserProfile(models.Model): user = models.OneToOneField(User, related_name="profile", on_delete=models.CASCADE) ...
An user may not have an UserProfile instance so we will use such logic:
profile = getattr(request.user, "profile", UserProfile(user=request.user))
But django will always return the default value no matter request.user.profile
exists or not.
Here is the poc:
In [1]: u = User.objects.get(username='s') In [2]: u.profile Out[2]: <UserProfile: UserProfile object (5)> In [3]: getattr(u, 'profile', UserProfile()) Out[3]: <UserProfile: UserProfile object (5)> In [4]: getattr(u, 'profile', UserProfile(user=u)) Out[4]: <UserProfile: UserProfile object (None)>
the problem is UserProfile(user=u)
will update the u.profile
when we init UserProfile
.
I know this issue is caused by design, maybe we should update the document for such case.
Change History (2)
comment:1 by , 4 years ago
Description: | modified (diff) |
---|---|
Needs documentation: | set |
comment:2 by , 4 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
Note:
See TracTickets
for help on using tickets.
As far as I'm aware this is an expected behavior to keep relationships in sync. I don't think there is anything that we could improve in docs, there is also an example which shows this behavior:
You can use
hasattr()
or catchAttributeError
.