Default User Model OneToOneField Attribute Error

Viewed 153

I am trying to connect the default Django User model with another one I made to store extra info. but even after following all the proper steps, I am getting an error. I have spent way to much time trying to figure it out, hopefully, you guys can figure it out and help me. (you probably will you all are much smarter than me)

here is the import command :

from django.contrib.auth.models import User

here is the integration with the premade model:

class User_Info(models.Model):
    user = models.OneToOneField(User,null = True, on_delete = models.CASCADE)

here is the view I am using :

def userPage(request):
    _user_ = request.user.User_Info.all()
    trades = request.user.User_Info.trade_set.all()
    total_trades = trades.count()
    context = {"_user_" : _user_,"trades" : trades, "total_trades" : total_trades}
return render(request, "accounts/user.html", context)

This is the error I am getting:

AttributeError at /user/

'User' object has no attribute 'User_Info'

Request Method:GET

Request URL:http://127.0.0.1:8000/user/

Django Version:3.1.2Exception

Type:AttributeError

Exception Value:'User' object has no attribute 'User_Info'

if you need any more information let me know I will be more than happy to help!

Thank you for your time! :)

3 Answers

You've used the class name as an attribute, so I think you'll find it really helpful to set the related_name param on fields like this.

For example;

class User_Info(models.Model):
    user = models.OneToOneField(User, null=True, related_name='info', on_delete = models.CASCADE)

You can then access that in a view by doing;

def userPage(request):
    user = request.user
    user_info = user.info
    
    context = {
        "user" : user,
        "user_info" : user_info,
    }
    return render(request, "accounts/user.html", context)

You can read the docs on related_name here; https://docs.djangoproject.com/en/3.1/ref/models/fields/#django.db.models.ForeignKey.related_name

The default name of the relation in reverse is the name of the class with lowercase, so you access it with user_info:

def userPage(request):
    info = user.user_info
    trades = info.trade_set.all()
    total_trades = trades.count()
    context = {'_user_' : info, 'trades' : trades, 'total_trades' : total_trades}
return render(request, "accounts/user.html", context)

Or you can set the related_name=… parameter [Django-doc] in the OneToOneField to specify the name of the relation in reverse.

here are a few things I'd suggest. The code you have listed is trying to connect two classes together, not instances. So I would put a related_name='user_info' on your User_Info class, then you can call something like user.user_info.

I strongly recommend not using underscores in class names.

Also, allowing null = True for the relationship to User on a user annotation class seems very weird to me. User not having a User_Info instance is ok. User-Info instance without a User makes no sense to me.

Related