Opened 5 years ago
Closed 5 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 , 5 years ago
| Description: | modified (diff) |
|---|---|
| Needs documentation: | set |
comment:2 by , 5 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.