Ravin Kohli
Ravin Kohli

Reputation: 153

Userprofile does not exist user has no profile

For a wallet app I have created a profile for every user of the django.contrib.auth.models User model. when a user create an account their profile is created and saved. But when i try to add money i get an error called Userprofile does not exist user has no profile. So i checked the database and their the Userprofile with the correct user exists. I am really confused as to why this is happening.

//add_money view

def add_money(request):
    if request.user:
        if request.user.has_perm('add_money'):
            if request.POST and request.POST.get('amount'):
                username = request.user.username
                add_amount = request.POST.get('amount')
                wallet = Wallet.objects.get(pk=request.user.userprofile.wallet_id_id)
                wallet.add_money(add_amount)
                wallet.save()
                now = datetime.now()
                trans = Transaction(from_name=username, wallet_id=wallet, date=now, amount=add_amount)
                trans.save()
                return render(request, 'user_profile.html', {'user': request.user,'userprofile': request.user.userprofile, 'wallet': wallet})
            else:
                return render(request, 'add_money.html')
        else:
            return render(request, 'access_denied.html')
    else:
        return HttpResponseRedirect('/login/?next={}'.format('/add_money/'))

//create_user view

def create_user(request):
    form = UserReg(request.POST or None)
    if form.is_valid():
        user = form.save(commit=False)
        username = form.cleaned_data['username']
        password = form.cleaned_data['password']
        user.set_password(password)
        wallet = Wallet(username=request.POST['username'], amount=0)
        wallet.save()
        user.save()
        userprofile = Userprofile(user=user, wallet_id=wallet)
        userprofile.save()
        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                return render(request, 'user_profile.html', {'user': user, 'wallet': wallet})
    context = {
        "form": form,
    }
    return render(request, 'create_user.html',context)

//Userprofile model

class Userprofile(models.Model):
    user = models.OneToOneField(User, unique=True, primary_key=True)
    wallet_id = models.ForeignKey(Wallet, on_delete=models.CASCADE)
    date_ob = models.DateField(null=True, blank=True)
    sex = models.CharField(max_length=1, null=True)

    def __str__(self):
        return self.user

Database Image Database Image Traceback:

File "/Users/ravinkohli/env_app_pw/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/ravinkohli/PycharmProjects/untitled1/wallet/views.py" in add_money
  19.                 wallet = Wallet.objects.get(pk=request.user.userprofile.wallet_id_id)
File "/Users/ravinkohli/env_app_pw/lib/python2.7/site-packages/django/utils/functional.py" in inner
  226.         return func(self._wrapped, *args)
File "/Users/ravinkohli/env_app_pw/lib/python2.7/site-packages/django/db/models/fields/related.py" in __get__
  480.                     self.related.get_accessor_name()

Exception Type: RelatedObjectDoesNotExist at /add_money/
Exception Value: User has no userprofile.

**EDIT:

the problem was solved when i logged out of admin site on the other tab, i printed the request.user.username and the admin's username was displayed this was solved when i logged out. Thanks for your help**

Upvotes: 1

Views: 1956

Answers (1)

e4c5
e4c5

Reputation: 53734

Solution to this problem.

The error occurs at this line

 wallet = Wallet.objects.get(pk=request.user.userprofile.wallet_id_id)

Clearly because the userprofile doesn't exist for the user. This can be for two main reasons.

  1. the user is the anonymous user (not authenticated) you are not checking if the user is logged in
  2. the user account was created before you created the user profile.

check if the profile exists first

if not getattr(request.user,'userprofile'):
    # create user profile here

wallet = Wallet.objects.get(pk=request.user.userprofile.wallet_id_id)

The real solution

You have got your database design wrong. See this.

wallet = Wallet(username=request.POST['username'], amount=0)

This implies that you are having a username field in your wallet model, but then

class Userprofile(models.Model):
    user = models.OneToOneField(User, unique=True, primary_key=True)
    wallet_id = models.ForeignKey(Wallet, on_delete=models.CASCADE)

You have a wallet as a foreign key to a UserProfile which leads to a cyclic relationship.

The correct design would be to remove the username field from your Wallet and replace it with a user field

class Wallet(models.Model):
    user = models.ForeignKey(User)
    ...

Then your user profile becomes

class Userprofile(models.Model):
    user = models.OneToOneField(User, unique=True, primary_key=True)
    date_ob = models.DateField(null=True, blank=True)
    sex = models.CharField(max_length=1, null=True)

    def __str__(self):
        return self.user

Upvotes: 2

Related Questions