ValueError at /signup/ Cannot assign "<User: prosenjit>": "Referral.parent" must be a "Referral" instance

After reading a lot of answers similar to this problem I got a specific error in every single case. In the following, I have attached my mandatory code.

Models.py

import uuid
import enum
from django.db import models
from django.utils import timezone, translation
from django.conf import settings
from django.core.validators import MinValueValidator, MaxValueValidator
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation

from django_numerators.models import NumeratorMixin
from mptt.models import MPTTModel, TreeForeignKey, TreeManager

_ = translation.gettext_lazy
from .utils import generate_ref_code

class Referral(NumeratorMixin, MPTTModel, models.Model):
    class Meta:
        verbose_name = _('Referral')
        verbose_name_plural = _('Referral')
        unique_together = ('parent', 'account')

    limit = 3

    parent = TreeForeignKey(
        'self', null=True, blank=True,
        on_delete=models.SET_NULL,
        related_name='downlines',
        verbose_name=_('Up Line'))
    account = models.OneToOneField(
        get_user_model(),
        on_delete=models.CASCADE,
        verbose_name=_('account'))
    balance = models.DecimalField(
        default=0,
        max_digits=15,
        decimal_places=2,
        editable=False,
        verbose_name=_("Balance"))
    created_at = models.DateTimeField(
        default=timezone.now, editable=False)
    code = models.CharField(max_length=12, blank=True)

    def __str__(self):
        return (
            self.account.username
            if self.account.get_full_name() in ['', None]
            else self.account.get_full_name()
        )

    def update_balance(self, balance):
        self.balance = balance
        self.save()

    def get_referral_limit(self):
        return getattr(settings, 'REFERRAL_DOWNLINE_LIMIT', None) or self.limit

    def get_uplines(self):
        return self.get_ancestors(include_self=False, ascending=True)[:self.get_referral_limit()]

    def save(self, *args, **kwargs):
        if self.code == "":
            code = generate_ref_code()
            self.code = code
        super().save(*args, **kwargs)

Everything is working well and 100% worked if I add foreignkey instead of TreeForeignKey in the parent field

parent = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True, related_name='ref_by')

Instead Of

parent = TreeForeignKey(
            'self', null=True, blank=True,
            on_delete=models.SET_NULL,
            related_name='downlines',
            verbose_name=_('Up Line'))

But I need TreeForeignKey because of my multilevel referral system.

# utils.py

import uuid
import json
from django.core.serializers.json import DjangoJSONEncoder
from uuid import UUID
import random


def generate_ref_code():
    code = str(uuid.uuid4()).replace("-", "")[:12]

    return code

signals.py

from .models import Referral
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver


@receiver(post_save, sender=User)
def post_save_create_profile(sender, instance, created, *args, **kwargs):
    if created:
        Referral.objects.create(account=instance)

views.py

@csrf_protect
def signup_view(request):
    profile_id = request.session.get('ref_profile')
    print('profile_id', profile_id)
    form = SignupForm(request.POST or None)
    if form.is_valid():
        if profile_id is not None:
            recommended_by_profile = Referral.objects.get(id=profile_id)
            print("recommended_by_profile", recommended_by_profile)

            instance = form.save()
            print("instance saved", instance)
            registered_user = User.objects.get(id=instance.id)
            print("registered_user", registered_user)
            registered_profile = Referral.objects.get(account=registered_user)
            print("registered_profile", registered_profile)
            registered_profile.parent = recommended_by_profile.account
            print("registered_profile.parent", registered_profile.parent)
            # print("registered_profile.user", registered_profile.user)
            print("registered_profile.account", registered_profile.account)
            print("recommended_by_profile.parent", recommended_by_profile.parent)
            # print("recommended_by_profile.user", recommended_by_profile.user)
            print("recommended_by_profile.account", recommended_by_profile.account)
            registered_profile.save()
            print("registered_profile it's saved", registered_profile)
        else:
            print("Referral not working")
            form.save()
        username = form.cleaned_data.get('username')
        password = form.cleaned_data.get('password1')
        user = authenticate(username=username, password=password)
        login(request, user)
        return redirect('main_view')
    context = {
        'form': form
    }
    return render(request, 'signup.html', context)

I have also attached the image and video together of the error where you can see the specific one. Here are the main issues with a data type that is not passing on the “parent” field when using “TreeForeignKey”.

The Video Link Is Below

The Video

Any kind of help or suggestion would be appreciated related to the question.

Thanks

What type of object is self going to be in this instance? (What is the error message telling you?)

I wanted to send a user instance that should send a name. That will assign as a parent of a new user who will use the code.

But the “parent” name is the default “Mptt Model” field that I can’t change. And the parent field always sends me the parent’s name or “None”. But should be assigned the refer user name of the new user.

I tried to use it to send the parent id instead of the parent directly. In the view file, I tried to add this line
**

registered_profile.parent_id = recommended_by_profile.account.pk

**
It saved the name according to the id number. Randomly assigned the parent name. In this case, maybe I’m very close to the solution if I can send the exact user-id as a parent.

Finally, it’s working well if I send directly the id number as the parent.

registered_profile.parent_id = profile_id