Mohammad Abdollahzadeh
Mohammad Abdollahzadeh

Reputation: 418

'RelatedManager' object has no attribute 'save'

This is the models.py code

class Profile(models.Model):
    user = models.ForeignKey(User, unique=True, on_delete=models.CASCADE, related_name='profile')



@receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
    instance.profile.save()


@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    # Profile.objects.save()
    instance.profile.save()

and This the views.py code:

def signup(request):
    ....

    if request.method == "POST":
        user_form = UserRegistrationForm(request.POST)

        if user_form.is_valid():
            user = user_form.save(commit=False)
            user.save(using='default')
            login(request, user)
            return HttpResponse("User Loged In")

Then after fill the registration form and click the submit button, Django get me the following Error: 'RelatedManager' object has no attribute 'save'

Upvotes: 3

Views: 3197

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477513

You defined a ForeignKey from a Profile to a User, but that means every Profile is attached to a User, it is however perfectly possible that multiple Profiles are attached to the same User.

Hence if you use a_user.profile, it will not return a single Profile, but a RelatedManager: a manager that manages the collection (that can contain zero, one or multiple elements) of Profile.

I think however that you actually want to associated Profiles with distinct Users, in which case you better use a OneToOneField:

class Profile(models.Model):
    user = models.OneToOneField(User, unique=True, on_delete=models.CASCADE)

If you then query someuser.profile you will either get a Profile instance, or it will raise a Profile.DoesNotExists error in case no profile is associated with that user.

By default the related_name of a OneToOneField is the name of the class in lowercase, so you no longer need to specify this.

Note however that in your code instance.profile.save() is not necessary, since the Profile, is basically already saved by creating it:

@receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
    # unnecessary
    # instance.profile.save()

Upvotes: 8

Related Questions