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”.
Any kind of help or suggestion would be appreciated related to the question.
Thanks