67👍
Using a profile model with a relation to the built-in User
is still a totally legitimate construct for storing additional user information (and recommended in many cases). The AUTH_PROFILE_MODULE
and get_profile()
stuff that is now deprecated just ended up being unnecessary, given that built-in Django 1-to-1 syntax works cleanly and elegantly here.
The transition from the old usage is actually easy if you’re already using a OneToOneField
to User
on your profile model, which is how the profile module was recommended to be set up before get_profile was deprecated.
class UserProfile(models.Model):
user = OneToOneField(User, related_name="profile")
# add profile fields here, e.g.,
nickname = CharField(...)
# usage: no get_profile() needed. Just standard 1-to-1 reverse syntax!
nickname = request.user.profile.nickname
See here if you’re not familiar with the syntactic magic for OneToOneField
‘s that makes this possible. It ends up being a simple search and replace of get_profile()
for profile
or whatever your related_name
is (auto related name in the above case would be user_profile
). Standard django reverse 1-1 syntax is actually nicer than get_profile()
!
Change a ForeignKey to a OneToOneField
However, I realize this doesn’t answer your question entirely. You indicate that you used a ForeignKey
to User
in your profile module rather than a OneToOne
, which is fine, but the syntax isn’t as simple if you leave it as a ForeignKey
, as you note in your follow up comment.
Assuming you were using your ForeignKey
in practice as an unique foreign key (essentially a 1-to-1), given that in the DB a OneToOneField
is just a ForeignKey
field with a unique=True
constraint, you should be able to change the ForeignKey
field to a OneToOneField
in your code without actually having to make a significant database migration or incurring any data loss.
Dealing with South migration
If you’re using South for migrations, the code change from the previous section may confuse South into deleting the old field and creating a new one if you do a schemamigration --auto
, so you may need to manually edit the migration to do things right. One approach would be to create the schemamigration and then blank out the forwards and backwards methods so it doesn’t actually try to do anything, but so it still freezes the model properly as a OneToOneField
going forward. Then, if you want to do things perfectly, you should add the unique constraint to the corresponding database foreign key column as well. You can either do this manually with SQL, or via South (by either editing the migration methods manually, or by setting unique=True
on the ForeignKey
and creating a first South migration before you switch it to a OneToOneField
and do a second migration and blank out the forwards/backwards methods).