Xor0x
Xor0x

Reputation: 143

How to fix "Cant Update profile in Django"

I ran into such a problem. The account has the ability to change the plan from free to premium for a certain period. When a user selects a package and synchronizes it in a date base is not saved. What's my mistake? Here is the code

# model.py
CHOICES = [('Free', 'free'), ('Premium', 'premium')]
​
​
class MemberShip(models.Model):
    title = models.CharField("Title", max_length=100)
    period = models.IntegerField("Period", default=30)
    price = models.IntegerField("Price", default=2, help_text="Price in dollars")
​
    def __str__(self):
        return f'Plan - {self.title}'
​

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    status = models.CharField("Status", max_length=20, choices=CHOICES, default='Free')
    end_date = models.DateTimeField("End Date", blank=True, null=True)
    membership = models.ForeignKey(MemberShip, on_delete=models.SET_NULL, null=True, default=None)
​
    def __str__(self):
        return self.user.username
​
    # def get_absolute_url(self):
    #     return reverse('account:profile', args=['id', self.id])
​
​
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
​
​
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()
​
​
# form.py
class PremiumForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['membership']
​
​
# view.py
​
class GetPremium(LoginRequiredMixin, UpdateView):
    model = Profile
    form_class = PremiumForm
    template_name = 'account/premium.html'
    success_url = reverse_lazy('account:dashboard')
​
    def get_object(self, **kwargs):
        return get_object_or_404(User, pk=self.request.user.id)

Upvotes: 1

Views: 39

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476604

In your get_object, you use the wrong model: you here need a Profile object, not a User object:

class GetPremium(LoginRequiredMixin, UpdateView):
    model = Profile
    form_class = PremiumForm
    template_name = 'account/premium.html'
    success_url = reverse_lazy('account:dashboard')
​
    def get_object(self, **kwargs):
        return get_object_or_404(Profile, user=self.request.user)

Note that for the Profile, your reverse(..) should here pass a kwargs=... parameter with a key 'id' that maps to the id of your Profile:

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    status = models.CharField("Status", max_length=20, choices=CHOICES, default='Free')
    end_date = models.DateTimeField("End Date", blank=True, null=True)
    membership = models.ForeignKey(MemberShip, on_delete=models.SET_NULL, null=True, default=None)
​
    def __str__(self):
        return self.user.username
​
    def get_absolute_url(self):
        return reverse('account:profile', kargs={'id': self.id})

Upvotes: 1

Related Questions